diff --git a/broker/core/src/misc/parse_perfdata.cc b/broker/core/src/misc/parse_perfdata.cc index 5ea51f8c4e6..4f53eac7a3c 100644 --- a/broker/core/src/misc/parse_perfdata.cc +++ b/broker/core/src/misc/parse_perfdata.cc @@ -16,6 +16,7 @@ * For more information : contact@centreon.com */ +#include #include #include #include @@ -130,6 +131,8 @@ std::list misc::parse_perfdata( uint32_t service_id, const char* str, const std::shared_ptr& logger) { + absl::flat_hash_set metric_name; + std::string_view current_name; std::list retval; auto id = [host_id, service_id] { if (host_id || service_id) @@ -206,11 +209,20 @@ std::list misc::parse_perfdata( } if (end - s + 1 > 0) { + current_name = std::string_view(s, end - s + 1); std::string name(s, end - s + 1); - name.resize(misc::string::adjust_size_utf8( - name, get_centreon_storage_metrics_col_size( - centreon_storage_metrics_metric_name))); - p.name(std::move(name)); + if (metric_name.contains(current_name)) { + logger->warn( + "storage: The metric '{}' appears several times in the output " + "\"{}\": you will lose any new occurence of this metric", + name, str); + error = true; + } else { + name.resize(misc::string::adjust_size_utf8( + name, get_centreon_storage_metrics_col_size( + centreon_storage_metrics_metric_name))); + p.name(std::move(name)); + } } else { logger->error("In service {}, metric name empty before '{}...'", id(), fmt::string_view(s, 10)); @@ -302,7 +314,8 @@ std::list misc::parse_perfdata( p.max()); // Append to list. - retval.emplace_back(std::move(p)); + metric_name.insert(current_name); + retval.push_back(std::move(p)); // Skip whitespaces. while (isspace(*tmp)) diff --git a/broker/core/src/misc/perfdata.cc b/broker/core/src/misc/perfdata.cc index b21d1f66764..a229497643c 100644 --- a/broker/core/src/misc/perfdata.cc +++ b/broker/core/src/misc/perfdata.cc @@ -1,5 +1,5 @@ /** - * Copyright 2011-2013 Centreon + * Copyright 2011-2024 Centreon * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ */ #include "com/centreon/broker/misc/perfdata.hh" - #include using namespace com::centreon::broker::misc; diff --git a/broker/core/test/misc/perfdata.cc b/broker/core/test/misc/perfdata.cc index be3f6071038..15e3c55f8c6 100644 --- a/broker/core/test/misc/perfdata.cc +++ b/broker/core/test/misc/perfdata.cc @@ -253,6 +253,58 @@ TEST_F(MiscParserParsePerfdata, Simple2) { ASSERT_TRUE(expected == *it); } +TEST_F(MiscParserParsePerfdata, SeveralIdenticalMetrics) { + // Parse perfdata. + std::list list{misc::parse_perfdata( + 0, 0, "'et'=18.00%;15:;10:;0;100 other=15 et=13.00%", _logger)}; + + // Assertions. + ASSERT_EQ(list.size(), 2u); + std::list::const_iterator it = list.begin(); + misc::perfdata expected; + expected.name("et"); + expected.value_type(misc::perfdata::gauge); + expected.value(18.0); + expected.unit("%"); + expected.warning(std::numeric_limits::infinity()); + expected.warning_low(15.0); + expected.critical(std::numeric_limits::infinity()); + expected.critical_low(10.0); + expected.min(0.0); + expected.max(100.0); + ASSERT_TRUE(expected == *it); + ++it; + ASSERT_EQ(it->name(), std::string_view("other")); + ASSERT_EQ(it->value(), 15); + ASSERT_EQ(it->value_type(), misc::perfdata::gauge); +} + +TEST_F(MiscParserParsePerfdata, ComplexSeveralIdenticalMetrics) { + // Parse perfdata. + std::list list{misc::parse_perfdata( + 0, 0, "'d[foo]'=18.00%;15:;10:;0;100 other=15 a[foo]=13.00%", _logger)}; + + // Assertions. + ASSERT_EQ(list.size(), 2u); + std::list::const_iterator it = list.begin(); + misc::perfdata expected; + expected.name("foo"); + expected.value_type(misc::perfdata::derive); + expected.value(18.0); + expected.unit("%"); + expected.warning(std::numeric_limits::infinity()); + expected.warning_low(15.0); + expected.critical(std::numeric_limits::infinity()); + expected.critical_low(10.0); + expected.min(0.0); + expected.max(100.0); + ASSERT_TRUE(expected == *it); + ++it; + ASSERT_EQ(it->name(), std::string_view("other")); + ASSERT_EQ(it->value(), 15); + ASSERT_EQ(it->value_type(), misc::perfdata::gauge); +} + TEST_F(MiscParserParsePerfdata, Complex1) { // Parse perfdata. std::list list{misc::parse_perfdata(