#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"
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>();
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<PerfdataValue>(perfdata_prefix + "idle", Convert::ToDouble(idle)));
+ perfdata->Add(make_shared<PerfdataValue>(perfdata_prefix + "pending", Convert::ToDouble(pending)));
}
status->Set("checkercomponent", nodes);
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);
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>();
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);
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>();
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);
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>();
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);
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>();
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);
* 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"
#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 <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp>
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<Dictionary>();
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);
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);
* 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"
#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 <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp>
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>();
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);
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);
******************************************************************************/
#include "livestatus/livestatuslistener.hpp"
+#include "icinga/perfdatavalue.hpp"
#include "config/configcompilercontext.hpp"
#include "base/utility.hpp"
#include "base/objectlock.hpp"
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>();
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);
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);
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>();
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);
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>();
void GraphiteWriter::SendPerfdata(const String& prefix, const CheckResult::Ptr& cr)
{
- Value pdv = 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;
+ Array::Ptr perfdata = cr->GetPerformanceData();
ObjectLock olock(perfdata);
- BOOST_FOREACH(const Dictionary::Pair& kv, perfdata) {
- double valueNum;
-
- if (!kv.second.IsObjectType<PerfdataValue>())
- valueNum = kv.second;
- else
- valueNum = static_cast<PerfdataValue::Ptr>(kv.second)->GetValue();
-
- String escaped_key = kv.first;
+ BOOST_FOREACH(const Value& val, perfdata) {
+ PerfdataValue::Ptr pdv;
+
+ if (val.IsObjectType<PerfdataValue>())
+ 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());
}
}
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);
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>();
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);
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>();
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);
: 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);
}
#include "base/registry.hpp"
#include "base/value.hpp"
#include "base/dictionary.hpp"
+#include "base/array.hpp"
#include <boost/function.hpp>
namespace icinga
public:
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);
- Value Invoke(Dictionary::Ptr& status, Dictionary::Ptr& perfdata);
+ Value Invoke(Dictionary::Ptr& status, Array::Ptr& perfdata);
private:
Callback m_Callback;
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>();
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);
[state, enum] ServiceState "state";
[state] String output;
- [state] Value performance_data;
+ [state] Array::Ptr performance_data;
[state] bool active {
default {{{ return true; }}}
* 'perfdata' must be a flat dictionary with double values
* '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 perfdata = make_shared<Dictionary>();
+ Array::Ptr perfdata = make_shared<Array>();
String name;
Value ret;
#include "icinga/i2-icinga.hpp"
#include "base/ringbuffer.hpp"
#include "base/dictionary.hpp"
+#include "base/array.hpp"
namespace icinga
{
static HostStatistics CalculateHostStats(void);
static ServiceStatistics CalculateServiceStats(void);
- static std::pair<Dictionary::Ptr, Dictionary::Ptr> GetFeatureStats(void);
+ static std::pair<Dictionary::Ptr, Array::Ptr> GetFeatureStats(void);
private:
CIB(void);
CheckResult::Ptr result = make_shared<CheckResult>();
std::pair<String, String> 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;
CheckResult::Ptr result = make_shared<CheckResult>();
std::pair<String, String> 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);
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>();
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);
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 bag = make_shared<Dictionary>();
/* 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_perfdata", stats.second);
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:
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);
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<String> 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);
if (!max.IsEmpty())
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();
- 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;
+
+ if (GetCounter())
+ unit = "c";
+ else if (GetUnit() == "seconds")
+ unit = "s";
+ else if (GetUnit() == "percent")
+ unit = "%";
+ else if (GetUnit() == "bytes")
+ unit = "B";
- result << unit;
+ result << unit;
- if (!pdv->GetWarn().IsEmpty()) {
- result << ";" << pdv->GetWarn();
+ if (!GetWarn().IsEmpty()) {
+ result << ";" << Convert::ToString(GetWarn());
- if (!pdv->GetCrit().IsEmpty()) {
- result << ";" << pdv->GetCrit();
+ if (!GetCrit().IsEmpty()) {
+ result << ";" << Convert::ToString(GetCrit());
- if (!pdv->GetMin().IsEmpty()) {
- result << ";" << pdv->GetMin();
+ if (!GetMin().IsEmpty()) {
+ result << ";" << Convert::ToString(GetMin());
- if (!pdv->GetMax().IsEmpty()) {
- result << ";" << pdv->GetMax();
- }
+ if (!GetMax().IsEmpty()) {
+ result << ";" << Convert::ToString(GetMax());
}
}
}
-
- return result.str();
- } else {
- return perfdata;
}
+
+ return result.str();
}
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;
};
}
safe class PerfdataValue
{
+ [state] String label;
[state] double value;
[state] bool counter;
[state] String unit;
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<Dictionary>();
+ Array::Ptr result = make_shared<Array>();
- 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<Dictionary>())
- 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<PerfdataValue>())
+ result << static_cast<PerfdataValue::Ptr>(pdv)->Format();
+ else
+ result << pdv;
}
return result.str();
static ServiceState ExitStatusToState(int exitStatus);
static std::pair<String, String> 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);
Dictionary::Ptr status = stats.first;
/* 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);
String connected_endpoints = FormatArray(status->Get("conn_endpoints"));
#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"
if (interval > 60)
interval = 60;
- Dictionary::Ptr perfdata = make_shared<Dictionary>();
-
- 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->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));
+ Array::Ptr perfdata = make_shared<Array>();
+
+ perfdata->Add(make_shared<PerfdataValue>("active_host_checks", CIB::GetActiveHostChecksStatistics(interval) / interval));
+ perfdata->Add(make_shared<PerfdataValue>("passive_host_checks", CIB::GetPassiveHostChecksStatistics(interval) / interval));
+ perfdata->Add(make_shared<PerfdataValue>("active_host_checks_1min", CIB::GetActiveHostChecksStatistics(60)));
+ perfdata->Add(make_shared<PerfdataValue>("passive_host_checks_1min", CIB::GetPassiveHostChecksStatistics(60)));
+ perfdata->Add(make_shared<PerfdataValue>("active_host_checks_5min", CIB::GetActiveHostChecksStatistics(60 * 5)));
+ perfdata->Add(make_shared<PerfdataValue>("passive_host_checks_5min", CIB::GetPassiveHostChecksStatistics(60 * 5)));
+ perfdata->Add(make_shared<PerfdataValue>("active_host_checks_15min", CIB::GetActiveHostChecksStatistics(60 * 15)));
+ perfdata->Add(make_shared<PerfdataValue>("passive_host_checks_15min", CIB::GetPassiveHostChecksStatistics(60 * 15)));
+
+ perfdata->Add(make_shared<PerfdataValue>("active_service_checks", CIB::GetActiveServiceChecksStatistics(interval) / interval));
+ perfdata->Add(make_shared<PerfdataValue>("passive_service_checks", CIB::GetPassiveServiceChecksStatistics(interval) / interval));
+ perfdata->Add(make_shared<PerfdataValue>("active_service_checks_1min", CIB::GetActiveServiceChecksStatistics(60)));
+ perfdata->Add(make_shared<PerfdataValue>("passive_service_checks_1min", CIB::GetPassiveServiceChecksStatistics(60)));
+ perfdata->Add(make_shared<PerfdataValue>("active_service_checks_5min", CIB::GetActiveServiceChecksStatistics(60 * 5)));
+ perfdata->Add(make_shared<PerfdataValue>("passive_service_checks_5min", CIB::GetPassiveServiceChecksStatistics(60 * 5)));
+ perfdata->Add(make_shared<PerfdataValue>("active_service_checks_15min", CIB::GetActiveServiceChecksStatistics(60 * 15)));
+ perfdata->Add(make_shared<PerfdataValue>("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<PerfdataValue>("min_latency", scs.min_latency));
+ perfdata->Add(make_shared<PerfdataValue>("max_latency", scs.max_latency));
+ perfdata->Add(make_shared<PerfdataValue>("avg_latency", scs.avg_latency));
+ perfdata->Add(make_shared<PerfdataValue>("min_execution_time", scs.min_latency));
+ perfdata->Add(make_shared<PerfdataValue>("max_execution_time", scs.max_latency));
+ perfdata->Add(make_shared<PerfdataValue>("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<PerfdataValue>("num_services_ok", ss.services_ok));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_warning", ss.services_warning));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_critical", ss.services_critical));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_unknown", ss.services_unknown));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_pending", ss.services_pending));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_unreachable", ss.services_unreachable));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_flapping", ss.services_flapping));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_in_downtime", ss.services_in_downtime));
+ perfdata->Add(make_shared<PerfdataValue>("num_services_acknowledged", ss.services_acknowledged));
double uptime = Utility::GetTime() - Application::GetStartTime();
- perfdata->Set("uptime", uptime);
+ perfdata->Add(make_shared<PerfdataValue>("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<PerfdataValue>("num_hosts_up", hs.hosts_up));
+ perfdata->Add(make_shared<PerfdataValue>("num_hosts_down", hs.hosts_down));
+ perfdata->Add(make_shared<PerfdataValue>("num_hosts_unreachable", hs.hosts_unreachable));
+ perfdata->Add(make_shared<PerfdataValue>("num_hosts_flapping", hs.hosts_flapping));
+ perfdata->Add(make_shared<PerfdataValue>("num_hosts_in_downtime", hs.hosts_in_downtime));
+ perfdata->Add(make_shared<PerfdataValue>("num_hosts_acknowledged", hs.hosts_acknowledged));
cr->SetOutput("Icinga 2 has been running for " + Utility::FormatDuration(uptime) +
". Version: " + Application::GetVersion());
# include <stdlib.h>
#endif /* _WIN32 */
#include "methods/nullchecktask.hpp"
+#include "icinga/perfdatavalue.hpp"
#include "base/utility.hpp"
#include "base/convert.hpp"
#include "base/scriptfunction.hpp"
String output = "Hello from ";
output += Utility::GetFQDN();
- Dictionary::Ptr perfdata = make_shared<Dictionary>();
- perfdata->Set("time", Convert::ToDouble(Utility::GetTime()));
+ Array::Ptr perfdata = make_shared<Array>();
+ perfdata->Add(make_shared<PerfdataValue>("time", Convert::ToDouble(Utility::GetTime())));
cr->SetOutput(output);
cr->SetPerformanceData(perfdata);
std::pair<String, String> 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);
#ifndef _WIN32
# include <stdlib.h>
#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"
String output = "Hello from ";
output += Utility::GetFQDN();
- Dictionary::Ptr perfdata = make_shared<Dictionary>();
- perfdata->Set("time", Convert::ToDouble(Utility::GetTime()));
+ Array::Ptr perfdata = make_shared<Array>();
+ perfdata->Add(make_shared<PerfdataValue>("time", Convert::ToDouble(Utility::GetTime())));
cr->SetOutput(output);
cr->SetPerformanceData(perfdata);
}
}
-Value ApiListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata)
+Value ApiListener::StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata)
{
Dictionary::Ptr nodes = make_shared<Dictionary>();
std::pair<Dictionary::Ptr, Dictionary::Ptr> stats;
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);
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);
void AddAnonymousClient(const ApiClient::Ptr& aclient);
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));
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");
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);
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);
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);
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);
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()