Fix problems with PNP4Nagios

fixes #7268
This commit is contained in:
Gunnar Beutner 2014-09-17 15:38:39 +02:00
parent bdb06be078
commit 879684efcd
50 changed files with 251 additions and 263 deletions

View File

@ -20,6 +20,7 @@
#include "checker/checkercomponent.hpp" #include "checker/checkercomponent.hpp"
#include "icinga/icingaapplication.hpp" #include "icinga/icingaapplication.hpp"
#include "icinga/cib.hpp" #include "icinga/cib.hpp"
#include "icinga/perfdatavalue.hpp"
#include "remote/apilistener.hpp" #include "remote/apilistener.hpp"
#include "base/dynamictype.hpp" #include "base/dynamictype.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
@ -36,7 +37,7 @@ REGISTER_TYPE(CheckerComponent);
REGISTER_STATSFUNCTION(CheckerComponentStats, &CheckerComponent::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();
@ -51,8 +52,8 @@ Value CheckerComponent::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perf
nodes->Set(checker->GetName(), stats); nodes->Set(checker->GetName(), stats);
String perfdata_prefix = "checkercomponent_" + checker->GetName() + "_"; String perfdata_prefix = "checkercomponent_" + checker->GetName() + "_";
perfdata->Set(perfdata_prefix + "idle", Convert::ToDouble(idle)); perfdata->Add(make_shared<PerfdataValue>(perfdata_prefix + "idle", Convert::ToDouble(idle)));
perfdata->Set(perfdata_prefix + "pending", Convert::ToDouble(pending)); perfdata->Add(make_shared<PerfdataValue>(perfdata_prefix + "pending", Convert::ToDouble(pending)));
} }
status->Set("checkercomponent", nodes); status->Set("checkercomponent", nodes);

View File

@ -72,7 +72,7 @@ public:
virtual void Start(void); virtual void Start(void);
virtual void Stop(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 GetIdleCheckables(void);
unsigned long GetPendingCheckables(void); unsigned long GetPendingCheckables(void);

View File

@ -38,7 +38,7 @@ REGISTER_TYPE(CheckResultReader);
REGISTER_STATSFUNCTION(CheckResultReaderStats, &CheckResultReader::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -38,7 +38,7 @@ public:
DECLARE_PTR_TYPEDEFS(CheckResultReader); DECLARE_PTR_TYPEDEFS(CheckResultReader);
DECLARE_TYPENAME(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: protected:
virtual void Start(void); virtual void Start(void);

View File

@ -45,7 +45,7 @@ REGISTER_SCRIPTFUNCTION(ValidateRotationMethod, &CompatLogger::ValidateRotationM
REGISTER_STATSFUNCTION(CompatLoggerStats, &CompatLogger::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -39,7 +39,7 @@ public:
DECLARE_PTR_TYPEDEFS(CompatLogger); DECLARE_PTR_TYPEDEFS(CompatLogger);
DECLARE_TYPENAME(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); static void ValidateRotationMethod(const String& location, const Dictionary::Ptr& attrs);

View File

@ -31,7 +31,7 @@ REGISTER_TYPE(ExternalCommandListener);
REGISTER_STATSFUNCTION(ExternalCommandListenerStats, &ExternalCommandListener::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -39,7 +39,7 @@ public:
DECLARE_PTR_TYPEDEFS(ExternalCommandListener); DECLARE_PTR_TYPEDEFS(ExternalCommandListener);
DECLARE_TYPENAME(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: protected:
virtual void Start(void); virtual void Start(void);

View File

@ -48,7 +48,7 @@ REGISTER_TYPE(StatusDataWriter);
REGISTER_STATSFUNCTION(StatusDataWriterStats, &StatusDataWriter::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -44,7 +44,7 @@ public:
DECLARE_PTR_TYPEDEFS(StatusDataWriter); DECLARE_PTR_TYPEDEFS(StatusDataWriter);
DECLARE_TYPENAME(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: protected:
virtual void Start(void); virtual void Start(void);

View File

@ -17,6 +17,10 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * 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/logger_fwd.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
@ -25,9 +29,6 @@
#include "base/dynamictype.hpp" #include "base/dynamictype.hpp"
#include "base/exception.hpp" #include "base/exception.hpp"
#include "base/statsfunction.hpp" #include "base/statsfunction.hpp"
#include "db_ido/dbtype.hpp"
#include "db_ido/dbvalue.hpp"
#include "db_ido_mysql/idomysqlconnection.hpp"
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -38,7 +39,7 @@ using namespace icinga;
REGISTER_TYPE(IdoMysqlConnection); REGISTER_TYPE(IdoMysqlConnection);
REGISTER_STATSFUNCTION(IdoMysqlConnectionStats, &IdoMysqlConnection::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();
@ -52,7 +53,7 @@ Value IdoMysqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe
nodes->Set(idomysqlconnection->GetName(), stats); nodes->Set(idomysqlconnection->GetName(), stats);
perfdata->Set("idomysqlconnection_" + idomysqlconnection->GetName() + "_query_queue_items", Convert::ToDouble(items)); perfdata->Add(make_shared<PerfdataValue>("idomysqlconnection_" + idomysqlconnection->GetName() + "_query_queue_items", items));
} }
status->Set("idomysqlconnection", nodes); status->Set("idomysqlconnection", nodes);

View File

@ -42,7 +42,7 @@ public:
DECLARE_PTR_TYPEDEFS(IdoMysqlConnection); DECLARE_PTR_TYPEDEFS(IdoMysqlConnection);
DECLARE_TYPENAME(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: protected:
virtual void Resume(void); virtual void Resume(void);

View File

@ -17,6 +17,10 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * 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/logger_fwd.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
@ -26,9 +30,6 @@
#include "base/exception.hpp" #include "base/exception.hpp"
#include "base/context.hpp" #include "base/context.hpp"
#include "base/statsfunction.hpp" #include "base/statsfunction.hpp"
#include "db_ido/dbtype.hpp"
#include "db_ido/dbvalue.hpp"
#include "db_ido_pgsql/idopgsqlconnection.hpp"
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -40,7 +41,7 @@ REGISTER_TYPE(IdoPgsqlConnection);
REGISTER_STATSFUNCTION(IdoPgsqlConnectionStats, &IdoPgsqlConnection::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();
@ -54,7 +55,7 @@ Value IdoPgsqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe
nodes->Set(idopgsqlconnection->GetName(), stats); nodes->Set(idopgsqlconnection->GetName(), stats);
perfdata->Set("idopgsqlconnection_" + idopgsqlconnection->GetName() + "_query_queue_items", Convert::ToDouble(items)); perfdata->Add(make_shared<PerfdataValue>("idopgsqlconnection_" + idopgsqlconnection->GetName() + "_query_queue_items", items));
} }
status->Set("idopgsqlconnection", nodes); status->Set("idopgsqlconnection", nodes);

View File

@ -42,7 +42,7 @@ public:
DECLARE_PTR_TYPEDEFS(IdoPgsqlConnection); DECLARE_PTR_TYPEDEFS(IdoPgsqlConnection);
DECLARE_TYPENAME(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: protected:
virtual void Resume(void); virtual void Resume(void);

View File

@ -18,6 +18,7 @@
******************************************************************************/ ******************************************************************************/
#include "livestatus/livestatuslistener.hpp" #include "livestatus/livestatuslistener.hpp"
#include "icinga/perfdatavalue.hpp"
#include "config/configcompilercontext.hpp" #include "config/configcompilercontext.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
@ -43,7 +44,7 @@ static boost::mutex l_ComponentMutex;
REGISTER_STATSFUNCTION(LivestatusListenerStats, &LivestatusListener::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();
@ -53,7 +54,7 @@ Value LivestatusListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe
nodes->Set(livestatuslistener->GetName(), stats); nodes->Set(livestatuslistener->GetName(), stats);
perfdata->Set("livestatuslistener_" + livestatuslistener->GetName() + "_connections", Convert::ToDouble(l_Connections)); perfdata->Add(make_shared<PerfdataValue>("livestatuslistener_" + livestatuslistener->GetName() + "_connections", l_Connections));
} }
status->Set("livestatuslistener", nodes); status->Set("livestatuslistener", nodes);

View File

@ -39,7 +39,7 @@ public:
DECLARE_PTR_TYPEDEFS(LivestatusListener); DECLARE_PTR_TYPEDEFS(LivestatusListener);
DECLARE_TYPENAME(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 GetClientsConnected(void);
static int GetConnections(void); static int GetConnections(void);

View File

@ -34,7 +34,7 @@ REGISTER_TYPE(NotificationComponent);
REGISTER_STATSFUNCTION(NotificationComponentStats, &NotificationComponent::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -37,7 +37,7 @@ public:
DECLARE_PTR_TYPEDEFS(NotificationComponent); DECLARE_PTR_TYPEDEFS(NotificationComponent);
DECLARE_TYPENAME(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); virtual void Start(void);

View File

@ -46,7 +46,7 @@ REGISTER_TYPE(GraphiteWriter);
REGISTER_STATSFUNCTION(GraphiteWriterStats, &GraphiteWriter::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();
@ -134,34 +134,28 @@ void GraphiteWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C
void GraphiteWriter::SendPerfdata(const String& prefix, const CheckResult::Ptr& cr) void GraphiteWriter::SendPerfdata(const String& prefix, const CheckResult::Ptr& cr)
{ {
Value pdv = cr->GetPerformanceData(); Array::Ptr perfdata = cr->GetPerformanceData();
if (pdv.IsEmpty())
return;
if (!pdv.IsObjectType<Dictionary>())
{
CONTEXT("Processing performance data value '" + String(pdv) + "'");
Log(LogWarning, "GraphiteWriter", "Could not send performance data: unparsed data.");
return;
}
Dictionary::Ptr perfdata = pdv;
ObjectLock olock(perfdata); ObjectLock olock(perfdata);
BOOST_FOREACH(const Dictionary::Pair& kv, perfdata) { BOOST_FOREACH(const Value& val, perfdata) {
double valueNum; PerfdataValue::Ptr pdv;
if (!kv.second.IsObjectType<PerfdataValue>()) if (val.IsObjectType<PerfdataValue>())
valueNum = kv.second; pdv = val;
else else {
valueNum = static_cast<PerfdataValue::Ptr>(kv.second)->GetValue(); try {
pdv = PerfdataValue::Parse(val);
} catch (const std::exception&) {
Log(LogWarning, "GraphiteWriter", "Ignoring invalid perfdata value: " + val);
continue;
}
}
String escaped_key = kv.first; String escaped_key = pdv->GetLabel();
SanitizeMetric(escaped_key); SanitizeMetric(escaped_key);
boost::algorithm::replace_all(escaped_key, "::", "."); boost::algorithm::replace_all(escaped_key, "::", ".");
SendMetric(prefix, escaped_key, valueNum); SendMetric(prefix, escaped_key, pdv->GetValue());
} }
} }

View File

@ -41,7 +41,7 @@ public:
DECLARE_PTR_TYPEDEFS(GraphiteWriter); DECLARE_PTR_TYPEDEFS(GraphiteWriter);
DECLARE_TYPENAME(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: protected:
virtual void Start(void); virtual void Start(void);

View File

@ -36,7 +36,7 @@ REGISTER_TYPE(PerfdataWriter);
REGISTER_STATSFUNCTION(PerfdataWriterStats, &PerfdataWriter::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -40,7 +40,7 @@ public:
DECLARE_PTR_TYPEDEFS(PerfdataWriter); DECLARE_PTR_TYPEDEFS(PerfdataWriter);
DECLARE_TYPENAME(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: protected:
virtual void Start(void); virtual void Start(void);

View File

@ -29,7 +29,7 @@ REGISTER_TYPE(FileLogger);
REGISTER_STATSFUNCTION(FileLoggerStats, &FileLogger::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -37,7 +37,7 @@ public:
DECLARE_PTR_TYPEDEFS(FileLogger); DECLARE_PTR_TYPEDEFS(FileLogger);
DECLARE_TYPENAME(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); virtual void Start(void);

View File

@ -27,7 +27,7 @@ StatsFunction::StatsFunction(const Callback& function)
: m_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); return m_Callback(status, perfdata);
} }

View File

@ -24,6 +24,7 @@
#include "base/registry.hpp" #include "base/registry.hpp"
#include "base/value.hpp" #include "base/value.hpp"
#include "base/dictionary.hpp" #include "base/dictionary.hpp"
#include "base/array.hpp"
#include <boost/function.hpp> #include <boost/function.hpp>
namespace icinga namespace icinga
@ -39,11 +40,11 @@ class I2_BASE_API StatsFunction : public Object
public: public:
DECLARE_PTR_TYPEDEFS(StatsFunction); DECLARE_PTR_TYPEDEFS(StatsFunction);
typedef boost::function<Value (Dictionary::Ptr& status, Dictionary::Ptr& perfdata)> Callback; typedef boost::function<Value (Dictionary::Ptr& status, Array::Ptr& perfdata)> Callback;
StatsFunction(const Callback& function); StatsFunction(const Callback& function);
Value Invoke(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); Value Invoke(Dictionary::Ptr& status, Array::Ptr& perfdata);
private: private:
Callback m_Callback; Callback m_Callback;

View File

@ -28,7 +28,7 @@ REGISTER_TYPE(SyslogLogger);
REGISTER_STATSFUNCTION(SyslogLoggerStats, &SyslogLogger::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -38,7 +38,7 @@ public:
DECLARE_PTR_TYPEDEFS(SyslogLogger); DECLARE_PTR_TYPEDEFS(SyslogLogger);
DECLARE_TYPENAME(SyslogLogger); DECLARE_TYPENAME(SyslogLogger);
static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); static Value StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata);
protected: protected:
virtual void ProcessLogEntry(const LogEntry& entry); virtual void ProcessLogEntry(const LogEntry& entry);

View File

@ -50,7 +50,7 @@ safe class CheckResult
[state, enum] ServiceState "state"; [state, enum] ServiceState "state";
[state] String output; [state] String output;
[state] Value performance_data; [state] Array::Ptr performance_data;
[state] bool active { [state] bool active {
default {{{ return true; }}} default {{{ return true; }}}

View File

@ -238,10 +238,10 @@ HostStatistics CIB::CalculateHostStats(void)
* 'perfdata' must be a flat dictionary with double values * 'perfdata' must be a flat dictionary with double values
* 'status' dictionary can contain multiple levels of dictionaries * 'status' dictionary can contain multiple levels of dictionaries
*/ */
std::pair<Dictionary::Ptr, Dictionary::Ptr> CIB::GetFeatureStats(void) std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats(void)
{ {
Dictionary::Ptr status = make_shared<Dictionary>(); Dictionary::Ptr status = make_shared<Dictionary>();
Dictionary::Ptr perfdata = make_shared<Dictionary>(); Array::Ptr perfdata = make_shared<Array>();
String name; String name;
Value ret; Value ret;

View File

@ -23,6 +23,7 @@
#include "icinga/i2-icinga.hpp" #include "icinga/i2-icinga.hpp"
#include "base/ringbuffer.hpp" #include "base/ringbuffer.hpp"
#include "base/dictionary.hpp" #include "base/dictionary.hpp"
#include "base/array.hpp"
namespace icinga namespace icinga
{ {
@ -84,7 +85,7 @@ public:
static HostStatistics CalculateHostStats(void); static HostStatistics CalculateHostStats(void);
static ServiceStatistics CalculateServiceStats(void); static ServiceStatistics CalculateServiceStats(void);
static std::pair<Dictionary::Ptr, Dictionary::Ptr> GetFeatureStats(void); static std::pair<Dictionary::Ptr, Array::Ptr> GetFeatureStats(void);
private: private:
CIB(void); CIB(void);

View File

@ -306,13 +306,7 @@ void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::ve
CheckResult::Ptr result = make_shared<CheckResult>(); CheckResult::Ptr result = make_shared<CheckResult>();
std::pair<String, String> co = PluginUtility::ParseCheckOutput(arguments[2]); std::pair<String, String> co = PluginUtility::ParseCheckOutput(arguments[2]);
result->SetOutput(co.first); result->SetOutput(co.first);
result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second));
Value perfdata = co.second;
if (host->GetEnablePerfdata())
perfdata = PluginUtility::ParsePerfdata(perfdata);
result->SetPerformanceData(perfdata);
ServiceState state; ServiceState state;
@ -358,13 +352,7 @@ void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std:
CheckResult::Ptr result = make_shared<CheckResult>(); CheckResult::Ptr result = make_shared<CheckResult>();
std::pair<String, String> co = PluginUtility::ParseCheckOutput(arguments[3]); std::pair<String, String> co = PluginUtility::ParseCheckOutput(arguments[3]);
result->SetOutput(co.first); result->SetOutput(co.first);
result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second));
Value perfdata = co.second;
if (service->GetEnablePerfdata())
perfdata = PluginUtility::ParsePerfdata(perfdata);
result->SetPerformanceData(perfdata);
result->SetState(PluginUtility::ExitStatusToState(exitStatus)); result->SetState(PluginUtility::ExitStatusToState(exitStatus));
result->SetScheduleStart(time); result->SetScheduleStart(time);

View File

@ -63,7 +63,7 @@ void IcingaApplication::StaticInitialize(void)
REGISTER_STATSFUNCTION(IcingaApplicationStats, &IcingaApplication::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();

View File

@ -42,7 +42,7 @@ public:
int Main(void); 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); static IcingaApplication::Ptr GetInstance(void);

View File

@ -34,7 +34,7 @@ REGISTER_TYPE(IcingaStatusWriter);
REGISTER_STATSFUNCTION(IcingaStatusWriterStats, &IcingaStatusWriter::StatsFunc); 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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();
@ -72,7 +72,7 @@ Dictionary::Ptr IcingaStatusWriter::GetStatusData(void)
Dictionary::Ptr bag = make_shared<Dictionary>(); Dictionary::Ptr bag = make_shared<Dictionary>();
/* features */ /* features */
std::pair<Dictionary::Ptr, Dictionary::Ptr> stats = CIB::GetFeatureStats(); std::pair<Dictionary::Ptr, Array::Ptr> stats = CIB::GetFeatureStats();
bag->Set("feature_status", stats.first); bag->Set("feature_status", stats.first);
bag->Set("feature_perfdata", stats.second); bag->Set("feature_perfdata", stats.second);

View File

@ -35,7 +35,7 @@ public:
DECLARE_PTR_TYPEDEFS(IcingaStatusWriter); DECLARE_PTR_TYPEDEFS(IcingaStatusWriter);
DECLARE_TYPENAME(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); static Dictionary::Ptr GetStatusData(void);
protected: protected:

View File

@ -31,9 +31,11 @@ REGISTER_TYPE(PerfdataValue);
PerfdataValue::PerfdataValue(void) PerfdataValue::PerfdataValue(void)
{ } { }
PerfdataValue::PerfdataValue(double value, bool counter, const String& unit, PerfdataValue::PerfdataValue(String label, double value, bool counter,
const Value& warn, const Value& crit, const Value& min, const Value& max) const String& unit, const Value& warn, const Value& crit, const Value& min,
const Value& max)
{ {
SetLabel(label);
SetValue(value); SetValue(value);
SetCounter(counter); SetCounter(counter);
SetUnit(unit); SetUnit(unit);
@ -43,23 +45,38 @@ PerfdataValue::PerfdataValue(double value, bool counter, const String& unit,
SetMax(max); 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) String label = perfdata.SubStr(0, eqp);
return value;
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<String> tokens; std::vector<String> tokens;
boost::algorithm::split(tokens, perfdata, boost::is_any_of(";")); boost::algorithm::split(tokens, valueStr, boost::is_any_of(";"));
bool counter = false; bool counter = false;
String unit; String unit;
Value warn, crit, min, max; 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); boost::algorithm::to_lower(unit);
@ -122,48 +139,48 @@ Value PerfdataValue::Parse(const String& perfdata)
if (!max.IsEmpty()) if (!max.IsEmpty())
max = max * base; max = max * base;
return make_shared<PerfdataValue>(value, counter, unit, warn, crit, min, max); return make_shared<PerfdataValue>(label, value, counter, unit, warn, crit, min, max);
} }
String PerfdataValue::Format(const Value& perfdata) String PerfdataValue::Format(void) const
{ {
if (perfdata.IsObjectType<PerfdataValue>()) {
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();
result << "=" << Convert::ToString(GetValue());
String unit; String unit;
if (pdv->GetCounter()) if (GetCounter())
unit = "c"; unit = "c";
else if (pdv->GetUnit() == "seconds") else if (GetUnit() == "seconds")
unit = "s"; unit = "s";
else if (pdv->GetUnit() == "percent") else if (GetUnit() == "percent")
unit = "%"; unit = "%";
else if (pdv->GetUnit() == "bytes") else if (GetUnit() == "bytes")
unit = "B"; unit = "B";
result << unit; result << unit;
if (!pdv->GetWarn().IsEmpty()) { if (!GetWarn().IsEmpty()) {
result << ";" << pdv->GetWarn(); result << ";" << Convert::ToString(GetWarn());
if (!pdv->GetCrit().IsEmpty()) { if (!GetCrit().IsEmpty()) {
result << ";" << pdv->GetCrit(); result << ";" << Convert::ToString(GetCrit());
if (!pdv->GetMin().IsEmpty()) { if (!GetMin().IsEmpty()) {
result << ";" << pdv->GetMin(); result << ";" << Convert::ToString(GetMin());
if (!pdv->GetMax().IsEmpty()) { if (!GetMax().IsEmpty()) {
result << ";" << pdv->GetMax(); result << ";" << Convert::ToString(GetMax());
} }
} }
} }
} }
return result.str(); return result.str();
} else {
return perfdata;
}
} }

View File

@ -33,12 +33,12 @@ public:
PerfdataValue(void); 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& warn = Empty, const Value& crit = Empty,
const Value& min = Empty, const Value& max = Empty); const Value& min = Empty, const Value& max = Empty);
static Value Parse(const String& perfdata); static PerfdataValue::Ptr Parse(const String& perfdata);
static String Format(const Value& perfdata); String Format(void) const;
}; };
} }

View File

@ -5,6 +5,7 @@ namespace icinga
safe class PerfdataValue safe class PerfdataValue
{ {
[state] String label;
[state] double value; [state] double value;
[state] bool counter; [state] bool counter;
[state] String unit; [state] String unit;

View File

@ -220,10 +220,9 @@ std::pair<String, String> PluginUtility::ParseCheckOutput(const String& output)
return std::make_pair(text, perfdata); return std::make_pair(text, perfdata);
} }
Value PluginUtility::ParsePerfdata(const String& perfdata) Array::Ptr PluginUtility::SplitPerfdata(const String& perfdata)
{ {
try { Array::Ptr result = make_shared<Array>();
Dictionary::Ptr result = make_shared<Dictionary>();
size_t begin = 0; size_t begin = 0;
String multi_prefix; String multi_prefix;
@ -234,12 +233,12 @@ Value PluginUtility::ParsePerfdata(const String& perfdata)
if (eqp == String::NPos) if (eqp == String::NPos)
break; 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] == '\'') if (label.GetLength() > 2 && label[0] == '\'' && label[label.GetLength() - 1] == '\'')
key = key.SubStr(1, key.GetLength() - 2); label = label.SubStr(1, label.GetLength() - 2);
size_t multi_index = key.RFind("::"); size_t multi_index = label.RFind("::");
if (multi_index != String::NPos) if (multi_index != String::NPos)
multi_prefix = ""; multi_prefix = "";
@ -252,48 +251,42 @@ Value PluginUtility::ParsePerfdata(const String& perfdata)
String value = perfdata.SubStr(eqp + 1, spq - eqp - 1); String value = perfdata.SubStr(eqp + 1, spq - eqp - 1);
if (!multi_prefix.IsEmpty()) if (!multi_prefix.IsEmpty())
key = multi_prefix + "::" + key; label = multi_prefix + "::" + label;
result->Set(key, PerfdataValue::Parse(value)); String pdv;
if (label.FindFirstOf(" ") != String::NPos)
pdv = "'" + label + "'=" + value;
else
pdv = label + "=" + value;
result->Add(pdv);
if (multi_index != String::NPos) if (multi_index != String::NPos)
multi_prefix = key.SubStr(0, multi_index); multi_prefix = label.SubStr(0, multi_index);
begin = spq + 1; begin = spq + 1;
} }
return result; return result;
} catch (const std::exception& ex) {
Log(LogWarning, "PluginUtility", "Error parsing performance data '" + perfdata + "': " + ex.what());
return perfdata;
}
} }
String PluginUtility::FormatPerfdata(const Value& perfdata) String PluginUtility::FormatPerfdata(const Array::Ptr& perfdata)
{ {
std::ostringstream result; std::ostringstream result;
if (!perfdata.IsObjectType<Dictionary>()) ObjectLock olock(perfdata);
return perfdata;
Dictionary::Ptr dict = perfdata;
ObjectLock olock(dict);
bool first = true; bool first = true;
BOOST_FOREACH(const Dictionary::Pair& kv, dict) { BOOST_FOREACH(const Value& pdv, perfdata) {
String key;
if (kv.first.FindFirstOf(" ") != String::NPos)
key = "'" + kv.first + "'";
else
key = kv.first;
if (!first) if (!first)
result << " "; result << " ";
else else
first = false; first = false;
result << key << "=" << PerfdataValue::Format(kv.second); if (pdv.IsObjectType<PerfdataValue>())
result << static_cast<PerfdataValue::Ptr>(pdv)->Format();
else
result << pdv;
} }
return result.str(); return result.str();

View File

@ -46,8 +46,8 @@ public:
static ServiceState ExitStatusToState(int exitStatus); static ServiceState ExitStatusToState(int exitStatus);
static std::pair<String, String> ParseCheckOutput(const String& output); static std::pair<String, String> ParseCheckOutput(const String& output);
static Value ParsePerfdata(const String& perfdata); static Array::Ptr SplitPerfdata(const String& perfdata);
static String FormatPerfdata(const Value& perfdata); static String FormatPerfdata(const Array::Ptr& perfdata);
private: private:
PluginUtility(void); PluginUtility(void);

View File

@ -52,7 +52,7 @@ void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRe
Dictionary::Ptr status = stats.first; Dictionary::Ptr status = stats.first;
/* use feature stats perfdata */ /* use feature stats perfdata */
std::pair<Dictionary::Ptr, Dictionary::Ptr> feature_stats = CIB::GetFeatureStats(); std::pair<Dictionary::Ptr, Array::Ptr> feature_stats = CIB::GetFeatureStats();
cr->SetPerformanceData(feature_stats.second); cr->SetPerformanceData(feature_stats.second);
String connected_endpoints = FormatArray(status->Get("conn_endpoints")); String connected_endpoints = FormatArray(status->Get("conn_endpoints"));

View File

@ -21,6 +21,7 @@
#include "icinga/cib.hpp" #include "icinga/cib.hpp"
#include "icinga/service.hpp" #include "icinga/service.hpp"
#include "icinga/icingaapplication.hpp" #include "icinga/icingaapplication.hpp"
#include "icinga/perfdatavalue.hpp"
#include "base/application.hpp" #include "base/application.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
@ -38,58 +39,58 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResul
if (interval > 60) if (interval > 60)
interval = 60; interval = 60;
Dictionary::Ptr perfdata = make_shared<Dictionary>(); Array::Ptr perfdata = make_shared<Array>();
perfdata->Set("active_host_checks", CIB::GetActiveHostChecksStatistics(interval) / interval); perfdata->Add(make_shared<PerfdataValue>("active_host_checks", CIB::GetActiveHostChecksStatistics(interval) / interval));
perfdata->Set("passive_host_checks", CIB::GetPassiveHostChecksStatistics(interval) / interval); perfdata->Add(make_shared<PerfdataValue>("passive_host_checks", CIB::GetPassiveHostChecksStatistics(interval) / interval));
perfdata->Set("active_host_checks_1min", CIB::GetActiveHostChecksStatistics(60)); perfdata->Add(make_shared<PerfdataValue>("active_host_checks_1min", CIB::GetActiveHostChecksStatistics(60)));
perfdata->Set("passive_host_checks_1min", CIB::GetPassiveHostChecksStatistics(60)); perfdata->Add(make_shared<PerfdataValue>("passive_host_checks_1min", CIB::GetPassiveHostChecksStatistics(60)));
perfdata->Set("active_host_checks_5min", CIB::GetActiveHostChecksStatistics(60 * 5)); perfdata->Add(make_shared<PerfdataValue>("active_host_checks_5min", CIB::GetActiveHostChecksStatistics(60 * 5)));
perfdata->Set("passive_host_checks_5min", CIB::GetPassiveHostChecksStatistics(60 * 5)); perfdata->Add(make_shared<PerfdataValue>("passive_host_checks_5min", CIB::GetPassiveHostChecksStatistics(60 * 5)));
perfdata->Set("active_host_checks_15min", CIB::GetActiveHostChecksStatistics(60 * 15)); perfdata->Add(make_shared<PerfdataValue>("active_host_checks_15min", CIB::GetActiveHostChecksStatistics(60 * 15)));
perfdata->Set("passive_host_checks_15min", CIB::GetPassiveHostChecksStatistics(60 * 15)); perfdata->Add(make_shared<PerfdataValue>("passive_host_checks_15min", CIB::GetPassiveHostChecksStatistics(60 * 15)));
perfdata->Set("active_service_checks", CIB::GetActiveServiceChecksStatistics(interval) / interval); perfdata->Add(make_shared<PerfdataValue>("active_service_checks", CIB::GetActiveServiceChecksStatistics(interval) / interval));
perfdata->Set("passive_service_checks", CIB::GetPassiveServiceChecksStatistics(interval) / interval); perfdata->Add(make_shared<PerfdataValue>("passive_service_checks", CIB::GetPassiveServiceChecksStatistics(interval) / interval));
perfdata->Set("active_service_checks_1min", CIB::GetActiveServiceChecksStatistics(60)); perfdata->Add(make_shared<PerfdataValue>("active_service_checks_1min", CIB::GetActiveServiceChecksStatistics(60)));
perfdata->Set("passive_service_checks_1min", CIB::GetPassiveServiceChecksStatistics(60)); perfdata->Add(make_shared<PerfdataValue>("passive_service_checks_1min", CIB::GetPassiveServiceChecksStatistics(60)));
perfdata->Set("active_service_checks_5min", CIB::GetActiveServiceChecksStatistics(60 * 5)); perfdata->Add(make_shared<PerfdataValue>("active_service_checks_5min", CIB::GetActiveServiceChecksStatistics(60 * 5)));
perfdata->Set("passive_service_checks_5min", CIB::GetPassiveServiceChecksStatistics(60 * 5)); perfdata->Add(make_shared<PerfdataValue>("passive_service_checks_5min", CIB::GetPassiveServiceChecksStatistics(60 * 5)));
perfdata->Set("active_service_checks_15min", CIB::GetActiveServiceChecksStatistics(60 * 15)); perfdata->Add(make_shared<PerfdataValue>("active_service_checks_15min", CIB::GetActiveServiceChecksStatistics(60 * 15)));
perfdata->Set("passive_service_checks_15min", CIB::GetPassiveServiceChecksStatistics(60 * 15)); perfdata->Add(make_shared<PerfdataValue>("passive_service_checks_15min", CIB::GetPassiveServiceChecksStatistics(60 * 15)));
CheckableCheckStatistics scs = CIB::CalculateServiceCheckStats(); CheckableCheckStatistics scs = CIB::CalculateServiceCheckStats();
perfdata->Set("min_latency", scs.min_latency); perfdata->Add(make_shared<PerfdataValue>("min_latency", scs.min_latency));
perfdata->Set("max_latency", scs.max_latency); perfdata->Add(make_shared<PerfdataValue>("max_latency", scs.max_latency));
perfdata->Set("avg_latency", scs.avg_latency); perfdata->Add(make_shared<PerfdataValue>("avg_latency", scs.avg_latency));
perfdata->Set("min_execution_time", scs.min_latency); perfdata->Add(make_shared<PerfdataValue>("min_execution_time", scs.min_latency));
perfdata->Set("max_execution_time", scs.max_latency); perfdata->Add(make_shared<PerfdataValue>("max_execution_time", scs.max_latency));
perfdata->Set("avg_execution_time", scs.avg_execution_time); perfdata->Add(make_shared<PerfdataValue>("avg_execution_time", scs.avg_execution_time));
ServiceStatistics ss = CIB::CalculateServiceStats(); ServiceStatistics ss = CIB::CalculateServiceStats();
perfdata->Set("num_services_ok", ss.services_ok); perfdata->Add(make_shared<PerfdataValue>("num_services_ok", ss.services_ok));
perfdata->Set("num_services_warning", ss.services_warning); perfdata->Add(make_shared<PerfdataValue>("num_services_warning", ss.services_warning));
perfdata->Set("num_services_critical", ss.services_critical); perfdata->Add(make_shared<PerfdataValue>("num_services_critical", ss.services_critical));
perfdata->Set("num_services_unknown", ss.services_unknown); perfdata->Add(make_shared<PerfdataValue>("num_services_unknown", ss.services_unknown));
perfdata->Set("num_services_pending", ss.services_pending); perfdata->Add(make_shared<PerfdataValue>("num_services_pending", ss.services_pending));
perfdata->Set("num_services_unreachable", ss.services_unreachable); perfdata->Add(make_shared<PerfdataValue>("num_services_unreachable", ss.services_unreachable));
perfdata->Set("num_services_flapping", ss.services_flapping); perfdata->Add(make_shared<PerfdataValue>("num_services_flapping", ss.services_flapping));
perfdata->Set("num_services_in_downtime", ss.services_in_downtime); perfdata->Add(make_shared<PerfdataValue>("num_services_in_downtime", ss.services_in_downtime));
perfdata->Set("num_services_acknowledged", ss.services_acknowledged); perfdata->Add(make_shared<PerfdataValue>("num_services_acknowledged", ss.services_acknowledged));
double uptime = Utility::GetTime() - Application::GetStartTime(); double uptime = Utility::GetTime() - Application::GetStartTime();
perfdata->Set("uptime", uptime); perfdata->Add(make_shared<PerfdataValue>("uptime", uptime));
HostStatistics hs = CIB::CalculateHostStats(); HostStatistics hs = CIB::CalculateHostStats();
perfdata->Set("num_hosts_up", hs.hosts_up); perfdata->Add(make_shared<PerfdataValue>("num_hosts_up", hs.hosts_up));
perfdata->Set("num_hosts_down", hs.hosts_down); perfdata->Add(make_shared<PerfdataValue>("num_hosts_down", hs.hosts_down));
perfdata->Set("num_hosts_unreachable", hs.hosts_unreachable); perfdata->Add(make_shared<PerfdataValue>("num_hosts_unreachable", hs.hosts_unreachable));
perfdata->Set("num_hosts_flapping", hs.hosts_flapping); perfdata->Add(make_shared<PerfdataValue>("num_hosts_flapping", hs.hosts_flapping));
perfdata->Set("num_hosts_in_downtime", hs.hosts_in_downtime); perfdata->Add(make_shared<PerfdataValue>("num_hosts_in_downtime", hs.hosts_in_downtime));
perfdata->Set("num_hosts_acknowledged", hs.hosts_acknowledged); perfdata->Add(make_shared<PerfdataValue>("num_hosts_acknowledged", hs.hosts_acknowledged));
cr->SetOutput("Icinga 2 has been running for " + Utility::FormatDuration(uptime) + cr->SetOutput("Icinga 2 has been running for " + Utility::FormatDuration(uptime) +
". Version: " + Application::GetVersion()); ". Version: " + Application::GetVersion());

View File

@ -21,6 +21,7 @@
# include <stdlib.h> # include <stdlib.h>
#endif /* _WIN32 */ #endif /* _WIN32 */
#include "methods/nullchecktask.hpp" #include "methods/nullchecktask.hpp"
#include "icinga/perfdatavalue.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
#include "base/scriptfunction.hpp" #include "base/scriptfunction.hpp"
@ -35,8 +36,8 @@ void NullCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResult:
String output = "Hello from "; String output = "Hello from ";
output += Utility::GetFQDN(); output += Utility::GetFQDN();
Dictionary::Ptr perfdata = make_shared<Dictionary>(); Array::Ptr perfdata = make_shared<Array>();
perfdata->Set("time", Convert::ToDouble(Utility::GetTime())); perfdata->Add(make_shared<PerfdataValue>("time", Convert::ToDouble(Utility::GetTime())));
cr->SetOutput(output); cr->SetOutput(output);
cr->SetPerformanceData(perfdata); cr->SetPerformanceData(perfdata);

View File

@ -68,13 +68,7 @@ void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, co
std::pair<String, String> co = PluginUtility::ParseCheckOutput(output); std::pair<String, String> co = PluginUtility::ParseCheckOutput(output);
cr->SetCommand(commandLine); cr->SetCommand(commandLine);
cr->SetOutput(co.first); cr->SetOutput(co.first);
cr->SetPerformanceData(PluginUtility::SplitPerfdata(co.second));
Value perfdata = co.second;
if (checkable->GetEnablePerfdata())
perfdata = PluginUtility::ParsePerfdata(perfdata);
cr->SetPerformanceData(perfdata);
cr->SetState(PluginUtility::ExitStatusToState(pr.ExitStatus)); cr->SetState(PluginUtility::ExitStatusToState(pr.ExitStatus));
cr->SetExitStatus(pr.ExitStatus); cr->SetExitStatus(pr.ExitStatus);
cr->SetExecutionStart(pr.ExecutionStart); cr->SetExecutionStart(pr.ExecutionStart);

View File

@ -20,8 +20,8 @@
#ifndef _WIN32 #ifndef _WIN32
# include <stdlib.h> # include <stdlib.h>
#endif /* _WIN32 */ #endif /* _WIN32 */
#include "icinga/icingaapplication.hpp"
#include "methods/randomchecktask.hpp" #include "methods/randomchecktask.hpp"
#include "icinga/perfdatavalue.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
#include "base/scriptfunction.hpp" #include "base/scriptfunction.hpp"
@ -36,8 +36,8 @@ void RandomCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResul
String output = "Hello from "; String output = "Hello from ";
output += Utility::GetFQDN(); output += Utility::GetFQDN();
Dictionary::Ptr perfdata = make_shared<Dictionary>(); Array::Ptr perfdata = make_shared<Array>();
perfdata->Set("time", Convert::ToDouble(Utility::GetTime())); perfdata->Add(make_shared<PerfdataValue>("time", Convert::ToDouble(Utility::GetTime())));
cr->SetOutput(output); cr->SetOutput(output);
cr->SetPerformanceData(perfdata); cr->SetPerformanceData(perfdata);

View File

@ -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<Dictionary>(); Dictionary::Ptr nodes = make_shared<Dictionary>();
std::pair<Dictionary::Ptr, Dictionary::Ptr> stats; std::pair<Dictionary::Ptr, Dictionary::Ptr> stats;
@ -724,8 +724,8 @@ Value ApiListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
stats = listener->GetStatus(); stats = listener->GetStatus();
BOOST_FOREACH(Dictionary::Pair const& kv, stats.second) BOOST_FOREACH(const Dictionary::Pair& kv, stats.second)
perfdata->Set("api_" + kv.first, kv.second); perfdata->Add("'api_" + kv.first + "'=" + Convert::ToString(kv.second));
status->Set("api", stats.first); status->Set("api", stats.first);

View File

@ -58,7 +58,7 @@ public:
void RelayMessage(const MessageOrigin& origin, const DynamicObject::Ptr& secobj, const Dictionary::Ptr& message, bool log); 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<Dictionary::Ptr, Dictionary::Ptr> GetStatus(void); std::pair<Dictionary::Ptr, Dictionary::Ptr> GetStatus(void);
void AddAnonymousClient(const ApiClient::Ptr& aclient); void AddAnonymousClient(const ApiClient::Ptr& aclient);

View File

@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(dictionary)
BOOST_AUTO_TEST_CASE(object) BOOST_AUTO_TEST_CASE(object)
{ {
PerfdataValue::Ptr pdv = make_shared<PerfdataValue>(100, true, "bytes"); PerfdataValue::Ptr pdv = make_shared<PerfdataValue>("size", 100, true, "bytes");
PerfdataValue::Ptr result = Deserialize(Serialize(pdv)); PerfdataValue::Ptr result = Deserialize(Serialize(pdv));

View File

@ -27,30 +27,34 @@ BOOST_AUTO_TEST_SUITE(icinga_perfdata)
BOOST_AUTO_TEST_CASE(empty) BOOST_AUTO_TEST_CASE(empty)
{ {
Dictionary::Ptr pd = PluginUtility::ParsePerfdata(""); Array::Ptr pd = PluginUtility::SplitPerfdata("");
BOOST_CHECK(pd->GetLength() == 0); BOOST_CHECK(pd->GetLength() == 0);
} }
BOOST_AUTO_TEST_CASE(simple) BOOST_AUTO_TEST_CASE(simple)
{ {
Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test=123456"); PerfdataValue::Ptr pdv = PerfdataValue::Parse("test=123456");
BOOST_CHECK(pd->Get("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_CHECK(str == "test=123456");
} }
BOOST_AUTO_TEST_CASE(quotes) BOOST_AUTO_TEST_CASE(quotes)
{ {
Dictionary::Ptr pd = PluginUtility::ParsePerfdata("'hello world'=123456"); Array::Ptr pd = PluginUtility::SplitPerfdata("'hello world'=123456");
BOOST_CHECK(pd->Get("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) BOOST_AUTO_TEST_CASE(multiple)
{ {
Dictionary::Ptr pd = PluginUtility::ParsePerfdata("testA=123456 testB=123456"); Array::Ptr pd = PluginUtility::SplitPerfdata("testA=123456 testB=123456");
BOOST_CHECK(pd->Get("testA") == 123456); BOOST_CHECK(pd->GetLength() == 2);
BOOST_CHECK(pd->Get("testB") == 123456);
String str = PluginUtility::FormatPerfdata(pd); String str = PluginUtility::FormatPerfdata(pd);
BOOST_CHECK(str == "testA=123456 testB=123456"); BOOST_CHECK(str == "testA=123456 testB=123456");
@ -58,9 +62,7 @@ BOOST_AUTO_TEST_CASE(multiple)
BOOST_AUTO_TEST_CASE(uom) BOOST_AUTO_TEST_CASE(uom)
{ {
Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test=123456B"); PerfdataValue::Ptr pv = PerfdataValue::Parse("test=123456B");
PerfdataValue::Ptr pv = pd->Get("test");
BOOST_CHECK(pv); BOOST_CHECK(pv);
BOOST_CHECK(pv->GetValue() == 123456); BOOST_CHECK(pv->GetValue() == 123456);
@ -71,13 +73,10 @@ BOOST_AUTO_TEST_CASE(uom)
BOOST_CHECK(pv->GetMin() == Empty); BOOST_CHECK(pv->GetMin() == Empty);
BOOST_CHECK(pv->GetMax() == Empty); BOOST_CHECK(pv->GetMax() == Empty);
String str = PluginUtility::FormatPerfdata(pd); String str = pv->Format();
BOOST_CHECK(str == "test=123456B"); BOOST_CHECK(str == "test=123456B");
pd = PluginUtility::ParsePerfdata("test=1000ms;200;500"); pv = PerfdataValue::Parse("test=1000ms;200;500");
BOOST_CHECK(pd);
pv = pd->Get("test");
BOOST_CHECK(pv); BOOST_CHECK(pv);
BOOST_CHECK(pv->GetValue() == 1); BOOST_CHECK(pv->GetValue() == 1);
@ -85,10 +84,7 @@ BOOST_AUTO_TEST_CASE(uom)
BOOST_CHECK(pv->GetWarn() == 0.2); BOOST_CHECK(pv->GetWarn() == 0.2);
BOOST_CHECK(pv->GetCrit() == 0.5); BOOST_CHECK(pv->GetCrit() == 0.5);
pd = PluginUtility::ParsePerfdata("test=1000ms"); pv = PerfdataValue::Parse("test=1000ms");
BOOST_CHECK(pd);
pv = pd->Get("test");
BOOST_CHECK(pv); BOOST_CHECK(pv);
BOOST_CHECK(pv->GetValue() == 1); BOOST_CHECK(pv->GetValue() == 1);
@ -98,15 +94,13 @@ BOOST_AUTO_TEST_CASE(uom)
BOOST_CHECK(pv->GetMin() == Empty); BOOST_CHECK(pv->GetMin() == Empty);
BOOST_CHECK(pv->GetMax() == Empty); BOOST_CHECK(pv->GetMax() == Empty);
str = PluginUtility::FormatPerfdata(pd); str = pv->Format();
BOOST_CHECK(str == "test=1s"); BOOST_CHECK(str == "test=1s");
} }
BOOST_AUTO_TEST_CASE(warncritminmax) BOOST_AUTO_TEST_CASE(warncritminmax)
{ {
Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test=123456B;1000;2000;3000;4000"); PerfdataValue::Ptr pv = PerfdataValue::Parse("test=123456B;1000;2000;3000;4000");
PerfdataValue::Ptr pv = pd->Get("test");
BOOST_CHECK(pv); BOOST_CHECK(pv);
BOOST_CHECK(pv->GetValue() == 123456); BOOST_CHECK(pv->GetValue() == 123456);
@ -117,21 +111,20 @@ BOOST_AUTO_TEST_CASE(warncritminmax)
BOOST_CHECK(pv->GetMin() == 3000); BOOST_CHECK(pv->GetMin() == 3000);
BOOST_CHECK(pv->GetMax() == 4000); BOOST_CHECK(pv->GetMax() == 4000);
String str = PluginUtility::FormatPerfdata(pd); BOOST_CHECK(pv->Format() == "test=123456B;1000;2000;3000;4000");
BOOST_CHECK(str == "test=123456B;1000;2000;3000;4000");
} }
BOOST_AUTO_TEST_CASE(invalid) BOOST_AUTO_TEST_CASE(invalid)
{ {
BOOST_CHECK(PluginUtility::ParsePerfdata("test=1,23456") == "test=1,23456"); BOOST_CHECK_THROW(PerfdataValue::Parse("test=1,23456"), boost::exception);
BOOST_CHECK(PluginUtility::ParsePerfdata("test=123456;10%;20%") == "test=123456;10%;20%"); BOOST_CHECK_THROW(PerfdataValue::Parse("test=123456;10%;20%"), boost::exception);
} }
BOOST_AUTO_TEST_CASE(multi) BOOST_AUTO_TEST_CASE(multi)
{ {
Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test::a=3 b=4"); Array::Ptr pd = PluginUtility::SplitPerfdata("test::a=3 b=4");
BOOST_CHECK(pd->Get("test::a") == 3); BOOST_CHECK(pd->Get(0) == "test::a=3");
BOOST_CHECK(pd->Get("test::b") == 4); BOOST_CHECK(pd->Get(1) == "test::b=4");
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()