diff --git a/doc/14-features.md b/doc/14-features.md index 5aa775c425..f7582301f5 100644 --- a/doc/14-features.md +++ b/doc/14-features.md @@ -370,7 +370,15 @@ See: [ElasticsearchWriter](09-object-types.md#objecttype-elasticsearchwriter) Metric values are stored like this: ``` -check_result.perfdata..value +check_result.perfdata: [ + { + "crit": 0, + "label": "example", + "min": 0, + "value": 0, + "warn": 0 + } +] ``` The following characters are escaped in perfdata labels: @@ -388,14 +396,7 @@ add more subsequent levels inside the tree. and is therefore replaced by `.`. Icinga 2 automatically adds the following threshold metrics -if existing: - -``` -check_result.perfdata..min -check_result.perfdata..max -check_result.perfdata..warn -check_result.perfdata..crit -``` +if existing: min, max, warn, crit Additionally it is possible to configure custom tags that are applied to the metrics via `host_tags_template` or `service_tags_template`. Depending on whether the write event was triggered on a service or host object, additional tags are added to the ElasticSearch entries. diff --git a/lib/perfdata/elasticsearchwriter.cpp b/lib/perfdata/elasticsearchwriter.cpp index 8e6848ab3f..e0ddad9eb7 100644 --- a/lib/perfdata/elasticsearchwriter.cpp +++ b/lib/perfdata/elasticsearchwriter.cpp @@ -189,6 +189,9 @@ void ElasticsearchWriter::AddCheckResult(const Dictionary::Ptr& fields, const Ch if (perfdata) { ObjectLock olock(perfdata); + + Array::Ptr perfdatapoints = new Array(); + for (const Value& val : perfdata) { PerfdataValue::Ptr pdv; @@ -212,22 +215,28 @@ void ElasticsearchWriter::AddCheckResult(const Dictionary::Ptr& fields, const Ch boost::replace_all(escapedKey, "\\", "_"); boost::algorithm::replace_all(escapedKey, "::", "."); - String perfdataPrefix = prefix + "perfdata." + escapedKey; + Dictionary::Ptr datapoint = new Dictionary(); - fields->Set(perfdataPrefix + ".value", pdv->GetValue()); + datapoint->Set("label", escapedKey); + datapoint->Set("value", pdv->GetValue()); if (!pdv->GetMin().IsEmpty()) - fields->Set(perfdataPrefix + ".min", pdv->GetMin()); + datapoint->Set("min", pdv->GetMin()); if (!pdv->GetMax().IsEmpty()) - fields->Set(perfdataPrefix + ".max", pdv->GetMax()); + datapoint->Set("max", pdv->GetMax()); if (!pdv->GetWarn().IsEmpty()) - fields->Set(perfdataPrefix + ".warn", pdv->GetWarn()); + datapoint->Set("warn", pdv->GetWarn()); if (!pdv->GetCrit().IsEmpty()) - fields->Set(perfdataPrefix + ".crit", pdv->GetCrit()); + datapoint->Set("crit", pdv->GetCrit()); if (!pdv->GetUnit().IsEmpty()) - fields->Set(perfdataPrefix + ".unit", pdv->GetUnit()); + datapoint->Set("unit", pdv->GetUnit()); + + perfdatapoints->Add(datapoint); } + + String perfdataPrefix = prefix + "perfdata"; + fields->Set(perfdataPrefix, std::move(perfdatapoints)); } }