This is an automated email from the ASF dual-hosted git repository. szaszm pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit 77a6c3519be5b62038595e08d909a5836618f9af Author: Gabor Gyimesi <[email protected]> AuthorDate: Thu Sep 22 15:44:12 2022 +0200 MINIFICPP-1901 Add agent identity to Prometheus metrics Closes #1385 Signed-off-by: Marton Szasz <[email protected]> --- METRICS.md | 84 ++++++++++++---------- conf/minifi.properties | 1 + .../integration/minifi/core/DockerTestCluster.py | 1 + docker/test/integration/minifi/core/ImageStore.py | 1 + encrypt-config/tests/ConfigFileEncryptorTests.cpp | 2 +- encrypt-config/tests/ConfigFileTests.cpp | 8 +-- encrypt-config/tests/resources/minifi.properties | 1 + ...th-additional-sensitive-props.minifi.properties | 1 + .../prometheus/PrometheusMetricsPublisher.cpp | 15 +++- extensions/prometheus/PrometheusMetricsPublisher.h | 2 + .../prometheus/PublishedMetricGaugeCollection.cpp | 5 +- .../prometheus/PublishedMetricGaugeCollection.h | 4 +- .../tests/PrometheusMetricsPublisherTest.cpp | 15 ++-- libminifi/include/properties/Configuration.h | 1 + libminifi/include/utils/OsUtils.h | 22 ++---- libminifi/src/Configuration.cpp | 1 + libminifi/src/utils/OsUtils.cpp | 20 +++--- .../test/resources/encrypted.minifi.properties | 1 + 18 files changed, 105 insertions(+), 80 deletions(-) diff --git a/METRICS.md b/METRICS.md index b53465a28..fa4b4c7b5 100644 --- a/METRICS.md +++ b/METRICS.md @@ -46,32 +46,46 @@ To use the publisher a port should also be configured where the metrics will be nifi.metrics.publisher.PrometheusMetricsPublisher.port=9936 -The last option defines which metric classes should be exposed through the metrics publisher in configured with a comma separated value: +The following option defines which metric classes should be exposed through the metrics publisher in configured with a comma separated value: # in minifi.properties nifi.metrics.publisher.metrics=QueueMetrics,RepositoryMetrics,GetFileMetrics,DeviceInfoNode,FlowInformation +An agent identifier should also be defined to identify which agent the metric is exposed from. If not set, the hostname is used as the identifier. + + # in minifi.properties + + nifi.metrics.publisher.agent.identifier=Agent1 + ## Metrics The following section defines the currently available metrics to be published by the MiNiFi C++ agent. NOTE: In Prometheus all metrics are extended with a `minifi_` prefix to mark the domain of the metric. For example the `connection_name` metric is published as `minifi_connection_name` in Prometheus. +### Generic labels + +The following labels are set for every single metric and are not listed separately in the labels of the metrics below. + +| Label | Description | +|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| +| metric_class | Class name to filter for this metric, set to the name of the metric e.g. QueueMetrics, GetFileMetrics | +| agent_identifier | Set to the identifier set in minifi.properties in the nifi.metrics.publisher.agent.identifier property. If not set the hostname is used | + ### QueueMetrics QueueMetrics is a system level metric that reports queue metrics for every connection in the flow. -| Metric name | Labels | Description | -|----------------------|------------------------------------------------|--------------------------------------------| -| queue_data_size | metric_class, connection_uuid, connection_name | Current queue data size | -| queue_data_size_max | metric_class, connection_uuid, connection_name | Max queue data size to apply back pressure | -| queue_size | metric_class, connection_uuid, connection_name | Current queue size | -| queue_size_max | metric_class, connection_uuid, connection_name | Max queue size to apply back pressure | +| Metric name | Labels | Description | +|----------------------|----------------------------------|--------------------------------------------| +| queue_data_size | connection_uuid, connection_name | Current queue data size | +| queue_data_size_max | connection_uuid, connection_name | Max queue data size to apply back pressure | +| queue_size | connection_uuid, connection_name | Current queue size | +| queue_size_max | connection_uuid, connection_name | Max queue size to apply back pressure | | Label | Description | |--------------------------|------------------------------------------------------------| -| metric_class | Class name to filter for this metric, set to QueueMetrics | | connection_uuid | UUID of the connection defined in the flow configuration | | connection_name | Name of the connection defined in the flow configuration | @@ -79,30 +93,28 @@ QueueMetrics is a system level metric that reports queue metrics for every conne RepositoryMetrics is a system level metric that reports metrics for the registered repositories (by default flowfile and provenance repository) -| Metric name | Labels | Description | -|----------------------|-------------------------------|---------------------------------------| -| is_running | metric_class, repository_name | Is the repository running (1 or 0) | -| is_full | metric_class, repository_name | Is the repository full (1 or 0) | -| repository_size | metric_class, repository_name | Current size of the repository | +| Metric name | Labels | Description | +|----------------------|-----------------|---------------------------------------| +| is_running | repository_name | Is the repository running (1 or 0) | +| is_full | repository_name | Is the repository full (1 or 0) | +| repository_size | repository_name | Current size of the repository | | Label | Description | |--------------------------|-----------------------------------------------------------------| -| metric_class | Class name to filter for this metric, set to RepositoryMetrics | | repository_name | Name of the reported repository | ### GetFileMetrics Processor level metric that reports metrics for the GetFile processor if defined in the flow configuration -| Metric name | Labels | Description | -|-----------------------|----------------------------------------------|------------------------------------------------| -| onTrigger_invocations | metric_class, processor_name, processor_uuid | Number of times the processor was triggered | -| accepted_files | metric_class, processor_name, processor_uuid | Number of files that matched the set criterias | -| input_bytes | metric_class, processor_name, processor_uuid | Sum of file sizes processed | +| Metric name | Labels | Description | +|-----------------------|--------------------------------|------------------------------------------------| +| onTrigger_invocations | processor_name, processor_uuid | Number of times the processor was triggered | +| accepted_files | processor_name, processor_uuid | Number of files that matched the set criterias | +| input_bytes | processor_name, processor_uuid | Sum of file sizes processed | | Label | Description | |----------------|----------------------------------------------------------------| -| metric_class | Class name to filter for this metric, set to GetFileMetrics | | processor_name | Name of the processor | | processor_uuid | UUID of the processor | @@ -110,13 +122,12 @@ Processor level metric that reports metrics for the GetFile processor if defined Processor level metric that reports metrics for the GetTCPMetrics processor if defined in the flow configuration -| Metric name | Labels | Description | -|-----------------------|----------------------------------------------|------------------------------------------------| -| onTrigger_invocations | metric_class, processor_name, processor_uuid | Number of times the processor was triggered | +| Metric name | Labels | Description | +|-----------------------|--------------------------------|------------------------------------------------| +| onTrigger_invocations | processor_name, processor_uuid | Number of times the processor was triggered | | Label | Description | |----------------|----------------------------------------------------------------| -| metric_class | Class name to filter for this metric, set to GetTCPMetrics | | processor_name | Name of the processor | | processor_uuid | UUID of the processor | @@ -126,29 +137,24 @@ DeviceInfoNode is a system level metric that reports metrics about the system re | Metric name | Labels | Description | |-----------------|--------------|---------------------------| -| physical_mem | metric_class | Physical memory available | -| memory_usage | metric_class | Memory used by the agent | -| cpu_utilization | metric_class | CPU utilized by the agent | - -| Label | Description | -|----------------|-------------------------------------------------------------| -| metric_class | Class name to filter for this metric, set to DeviceInfoNode | +| physical_mem | - | Physical memory available | +| memory_usage | - | Memory used by the agent | +| cpu_utilization | - | CPU utilized by the agent | ### FlowInformation DeviceInfoNode is a system level metric that reports metrics about the system resources used and available -| Metric name | Labels | Description | -|----------------------|------------------------------------------------|--------------------------------------------| -| queue_data_size | metric_class, connection_uuid, connection_name | Current queue data size | -| queue_data_size_max | metric_class, connection_uuid, connection_name | Max queue data size to apply back pressure | -| queue_size | metric_class, connection_uuid, connection_name | Current queue size | -| queue_size_max | metric_class, connection_uuid, connection_name | Max queue size to apply back pressure | -| is_running | metric_class, component_uuid, component_name | Check if the component is running (1 or 0) | +| Metric name | Labels | Description | +|----------------------|----------------------------------|--------------------------------------------| +| queue_data_size | connection_uuid, connection_name | Current queue data size | +| queue_data_size_max | connection_uuid, connection_name | Max queue data size to apply back pressure | +| queue_size | connection_uuid, connection_name | Current queue size | +| queue_size_max | connection_uuid, connection_name | Max queue size to apply back pressure | +| is_running | component_uuid, component_name | Check if the component is running (1 or 0) | | Label | Description | |-----------------|--------------------------------------------------------------| -| metric_class | Class name to filter for this metric, set to FlowInformation | | connection_uuid | UUID of the connection defined in the flow configuration | | connection_name | Name of the connection defined in the flow configuration | | component_uuid | UUID of the component | diff --git a/conf/minifi.properties b/conf/minifi.properties index 0dbf918a9..18190c096 100644 --- a/conf/minifi.properties +++ b/conf/minifi.properties @@ -123,6 +123,7 @@ nifi.jvm.options=-Xmx1G nifi.python.processor.dir=${MINIFI_HOME}/minifi-python/ # Publish metrics to external consumers +# nifi.metrics.publisher.agent.identifier= # nifi.metrics.publisher.class=PrometheusMetricsPublisher # nifi.metrics.publisher.PrometheusMetricsPublisher.port=9936 # nifi.metrics.publisher.metrics=QueueMetrics,RepositoryMetrics,GetFileMetrics,DeviceInfoNode,FlowInformation diff --git a/docker/test/integration/minifi/core/DockerTestCluster.py b/docker/test/integration/minifi/core/DockerTestCluster.py index 7aba844a7..51fa9fd30 100644 --- a/docker/test/integration/minifi/core/DockerTestCluster.py +++ b/docker/test/integration/minifi/core/DockerTestCluster.py @@ -387,4 +387,5 @@ class DockerTestCluster(SingleNodeDockerCluster): def verify_metric_exists(self, prometheus_client, metric_name, metric_class, labels={}): labels['metric_class'] = metric_class + labels['agent_identifier'] = "Agent1" return len(prometheus_client.get_current_metric_value(metric_name=metric_name, label_config=labels)) > 0 diff --git a/docker/test/integration/minifi/core/ImageStore.py b/docker/test/integration/minifi/core/ImageStore.py index d5ec680cc..23d46afaa 100644 --- a/docker/test/integration/minifi/core/ImageStore.py +++ b/docker/test/integration/minifi/core/ImageStore.py @@ -102,6 +102,7 @@ class ImageStore: echo "Database = postgres" >> /etc/odbc.ini RUN sed -i -e 's/INFO/DEBUG/g' {minifi_root}/conf/minifi-log.properties RUN echo nifi.flow.engine.threads=5 >> {minifi_root}/conf/minifi.properties + RUN echo nifi.metrics.publisher.agent.identifier=Agent1 >> {minifi_root}/conf/minifi.properties RUN echo nifi.metrics.publisher.class=PrometheusMetricsPublisher >> {minifi_root}/conf/minifi.properties RUN echo nifi.metrics.publisher.PrometheusMetricsPublisher.port=9936 >> {minifi_root}/conf/minifi.properties RUN echo nifi.metrics.publisher.metrics=RepositoryMetrics,QueueMetrics,GetFileMetrics,GetTCPMetrics,FlowInformation,DeviceInfoNode >> {minifi_root}/conf/minifi.properties diff --git a/encrypt-config/tests/ConfigFileEncryptorTests.cpp b/encrypt-config/tests/ConfigFileEncryptorTests.cpp index c9aa62cd2..f4a0b3d93 100644 --- a/encrypt-config/tests/ConfigFileEncryptorTests.cpp +++ b/encrypt-config/tests/ConfigFileEncryptorTests.cpp @@ -77,7 +77,7 @@ TEST_CASE("ConfigFileEncryptor can encrypt the sensitive properties", "[encrypt- uint32_t num_properties_encrypted = encryptSensitivePropertiesInFile(test_file, KEY); REQUIRE(num_properties_encrypted == 1); - REQUIRE(test_file.size() == 106); + REQUIRE(test_file.size() == 107); REQUIRE(check_encryption(test_file, Configuration::nifi_rest_api_password, original_password.length())); SECTION("calling encryptSensitiveProperties a second time does nothing") { diff --git a/encrypt-config/tests/ConfigFileTests.cpp b/encrypt-config/tests/ConfigFileTests.cpp index b8b24ccc0..e187b7edc 100644 --- a/encrypt-config/tests/ConfigFileTests.cpp +++ b/encrypt-config/tests/ConfigFileTests.cpp @@ -90,7 +90,7 @@ TEST_CASE("ConfigFile creates an empty object from a nonexistent file", "[encryp TEST_CASE("ConfigFile can parse a simple config file", "[encrypt-config][constructor]") { ConfigFile test_file{std::ifstream{"resources/minifi.properties"}}; - REQUIRE(test_file.size() == 105); + REQUIRE(test_file.size() == 106); } TEST_CASE("ConfigFile can test whether a key is present", "[encrypt-config][hasValue]") { @@ -102,7 +102,7 @@ TEST_CASE("ConfigFile can test whether a key is present", "[encrypt-config][hasV TEST_CASE("ConfigFile can read empty properties correctly", "[encrypt-config][constructor]") { ConfigFile test_file{std::ifstream{"resources/with-additional-sensitive-props.minifi.properties"}}; - REQUIRE(test_file.size() == 107); + REQUIRE(test_file.size() == 108); auto empty_property = test_file.getValue(Configuration::nifi_security_need_ClientAuth); REQUIRE(empty_property); @@ -143,7 +143,7 @@ TEST_CASE("ConfigFile can add a new setting after an existing setting", "[encryp SECTION("valid key") { test_file.insertAfter(Configuration::nifi_rest_api_password, "nifi.rest.api.password.protected", "my-cipher-name"); - REQUIRE(test_file.size() == 106); + REQUIRE(test_file.size() == 107); REQUIRE(test_file.getValue("nifi.rest.api.password.protected") == "my-cipher-name"); } @@ -158,7 +158,7 @@ TEST_CASE("ConfigFile can add a new setting at the end", "[encrypt-config][appen const std::string KEY = "nifi.bootstrap.sensitive.key"; const std::string VALUE = "aa411f289c91685ef9d5a9e5a4fad9393ff4c7a78ab978484323488caed7a9ab"; test_file.append(KEY, VALUE); - REQUIRE(test_file.size() == 106); + REQUIRE(test_file.size() == 107); REQUIRE(test_file.getValue(KEY) == std::make_optional(VALUE)); } diff --git a/encrypt-config/tests/resources/minifi.properties b/encrypt-config/tests/resources/minifi.properties index 7d1c73b01..ae12394b7 100644 --- a/encrypt-config/tests/resources/minifi.properties +++ b/encrypt-config/tests/resources/minifi.properties @@ -100,6 +100,7 @@ nifi.c2.flow.id= nifi.c2.flow.url= # Publish metrics to external consumers +# nifi.metrics.publisher.agent.identifier= # nifi.metrics.publisher.class=PrometheusMetricsPublisher # nifi.metrics.publisher.PrometheusMetricsPublisher.port=9936 # nifi.metrics.publisher.metrics=QueueMetrics,RepositoryMetrics,GetFileMetrics,DeviceInfoNode,FlowInformation diff --git a/encrypt-config/tests/resources/with-additional-sensitive-props.minifi.properties b/encrypt-config/tests/resources/with-additional-sensitive-props.minifi.properties index b3c7d8559..551029af2 100644 --- a/encrypt-config/tests/resources/with-additional-sensitive-props.minifi.properties +++ b/encrypt-config/tests/resources/with-additional-sensitive-props.minifi.properties @@ -102,6 +102,7 @@ nifi.c2.flow.id= nifi.c2.flow.url= # Publish metrics to external consumers +# nifi.metrics.publisher.agent.identifier= # nifi.metrics.publisher.class=PrometheusMetricsPublisher # nifi.metrics.publisher.PrometheusMetricsPublisher.port=9936 # nifi.metrics.publisher.metrics=QueueMetrics,RepositoryMetrics,GetFileMetrics,DeviceInfoNode,FlowInformation diff --git a/extensions/prometheus/PrometheusMetricsPublisher.cpp b/extensions/prometheus/PrometheusMetricsPublisher.cpp index 85f122120..56c866a4d 100644 --- a/extensions/prometheus/PrometheusMetricsPublisher.cpp +++ b/extensions/prometheus/PrometheusMetricsPublisher.cpp @@ -20,7 +20,9 @@ #include "core/Resource.h" #include "utils/StringUtils.h" +#include "utils/OsUtils.h" #include "PrometheusExposerWrapper.h" +#include "utils/Id.h" namespace org::apache::nifi::minifi::extensions::prometheus { @@ -35,6 +37,7 @@ void PrometheusMetricsPublisher::initialize(const std::shared_ptr<Configure>& co if (!exposer_) { exposer_ = std::make_unique<PrometheusExposerWrapper>(readPort()); } + loadAgentIdentifier(); loadMetricNodes(root); } @@ -61,7 +64,7 @@ void PrometheusMetricsPublisher::loadMetricNodes(core::ProcessGroup* root) { for (const auto& metric_node : nodes) { logger_->log_debug("Registering metric node '%s'", metric_node->getName()); - gauge_collections_.push_back(std::make_shared<PublishedMetricGaugeCollection>(metric_node)); + gauge_collections_.push_back(std::make_shared<PublishedMetricGaugeCollection>(metric_node, agent_identifier_)); exposer_->registerMetric(gauge_collections_.back()); } } @@ -82,6 +85,16 @@ std::vector<std::shared_ptr<state::response::ResponseNode>> PrometheusMetricsPub return nodes; } +void PrometheusMetricsPublisher::loadAgentIdentifier() { + auto agent_identifier = configuration_->get(Configure::nifi_metrics_publisher_agent_identifier); + if (agent_identifier && !agent_identifier->empty()) { + agent_identifier_ = *agent_identifier; + } else { + auto hostname = utils::OsUtils::getHostName(); + agent_identifier_ = hostname ? *hostname : "unknown-host-" + utils::IdGenerator::getIdGenerator()->generate().to_string(); + } +} + REGISTER_RESOURCE(PrometheusMetricsPublisher, DescriptionOnly); } // namespace org::apache::nifi::minifi::extensions::prometheus diff --git a/extensions/prometheus/PrometheusMetricsPublisher.h b/extensions/prometheus/PrometheusMetricsPublisher.h index b3ac09644..58451b077 100644 --- a/extensions/prometheus/PrometheusMetricsPublisher.h +++ b/extensions/prometheus/PrometheusMetricsPublisher.h @@ -44,12 +44,14 @@ class PrometheusMetricsPublisher : public core::CoreComponent, public state::Met private: uint32_t readPort(); std::vector<std::shared_ptr<state::response::ResponseNode>> getMetricNodes(core::ProcessGroup* root); + void loadAgentIdentifier(); std::mutex registered_metrics_mutex_; std::vector<std::shared_ptr<PublishedMetricGaugeCollection>> gauge_collections_; std::unique_ptr<MetricsExposer> exposer_; std::shared_ptr<Configure> configuration_; state::response::ResponseNodeLoader* response_node_loader_ = nullptr; + std::string agent_identifier_; std::shared_ptr<core::logging::Logger> logger_{core::logging::LoggerFactory<PrometheusMetricsPublisher>::getLogger()}; }; diff --git a/extensions/prometheus/PublishedMetricGaugeCollection.cpp b/extensions/prometheus/PublishedMetricGaugeCollection.cpp index e8974d386..81726749b 100644 --- a/extensions/prometheus/PublishedMetricGaugeCollection.cpp +++ b/extensions/prometheus/PublishedMetricGaugeCollection.cpp @@ -26,7 +26,9 @@ namespace org::apache::nifi::minifi::extensions::prometheus { -PublishedMetricGaugeCollection::PublishedMetricGaugeCollection(std::shared_ptr<state::PublishedMetricProvider> metric) : metric_{std::move(metric)} { +PublishedMetricGaugeCollection::PublishedMetricGaugeCollection(std::shared_ptr<state::PublishedMetricProvider> metric, std::string agent_identifier) + : metric_{std::move(metric)}, + agent_identifier_(std::move(agent_identifier)) { } std::vector<::prometheus::MetricFamily> PublishedMetricGaugeCollection::Collect() const { @@ -35,6 +37,7 @@ std::vector<::prometheus::MetricFamily> PublishedMetricGaugeCollection::Collect( ::prometheus::ClientMetric client_metric; client_metric.label = ranges::views::transform(metric.labels, [](auto&& kvp) { return ::prometheus::ClientMetric::Label{kvp.first, kvp.second}; }) | ranges::to<std::vector<::prometheus::ClientMetric::Label>>; + client_metric.label.push_back(::prometheus::ClientMetric::Label{"agent_identifier", agent_identifier_}); client_metric.gauge = ::prometheus::ClientMetric::Gauge{metric.value}; collection.push_back({ .name = "minifi_" + metric.name, diff --git a/extensions/prometheus/PublishedMetricGaugeCollection.h b/extensions/prometheus/PublishedMetricGaugeCollection.h index 8d8982a8f..0858e499f 100644 --- a/extensions/prometheus/PublishedMetricGaugeCollection.h +++ b/extensions/prometheus/PublishedMetricGaugeCollection.h @@ -18,6 +18,7 @@ #include <memory> #include <vector> +#include <string> #include "state/PublishedMetricProvider.h" #include "prometheus/collectable.h" @@ -27,11 +28,12 @@ namespace org::apache::nifi::minifi::extensions::prometheus { class PublishedMetricGaugeCollection : public ::prometheus::Collectable { public: - explicit PublishedMetricGaugeCollection(std::shared_ptr<state::PublishedMetricProvider> metric); + explicit PublishedMetricGaugeCollection(std::shared_ptr<state::PublishedMetricProvider> metric, std::string agent_identifier); std::vector<::prometheus::MetricFamily> Collect() const override; private: std::shared_ptr<state::PublishedMetricProvider> metric_; + std::string agent_identifier_; }; } // namespace org::apache::nifi::minifi::extensions::prometheus diff --git a/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp b/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp index b10b779d0..98e8d6afb 100644 --- a/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp +++ b/extensions/prometheus/tests/PrometheusMetricsPublisherTest.cpp @@ -24,7 +24,8 @@ #include "MetricsExposer.h" #include "core/state/nodes/ResponseNodeLoader.h" #include "core/RepositoryFactory.h" -#include "range/v3/algorithm/find.hpp" +#include "range/v3/algorithm/find_if.hpp" +#include "range/v3/algorithm/contains.hpp" namespace org::apache::nifi::minifi::extensions::prometheus::test { @@ -90,6 +91,7 @@ TEST_CASE_METHOD(PrometheusPublisherTestFixtureWithRealExposer, "Test prometheus TEST_CASE_METHOD(PrometheusPublisherTestFixtureWithDummyExposer, "Test adding metrics to exposer", "[prometheusPublisherTest]") { configuration_->set(Configure::nifi_metrics_publisher_metrics, "QueueMetrics,RepositoryMetrics,DeviceInfoNode,FlowInformation,AgentInformation,InvalidMetrics,GetFileMetrics,GetTCPMetrics"); + configuration_->set(Configure::nifi_metrics_publisher_agent_identifier, "AgentId-1"); publisher_->initialize(configuration_, response_node_loader_, nullptr); auto stored_metrics = exposer_->getMetrics(); std::vector<std::string> valid_metrics_without_flow = {"QueueMetrics", "RepositoryMetrics", "DeviceInfoNode", "FlowInformation", "AgentInformation"}; @@ -98,11 +100,12 @@ TEST_CASE_METHOD(PrometheusPublisherTestFixtureWithDummyExposer, "Test adding me auto collection = stored_metric->Collect(); for (const auto& metric_family : collection) { for (const auto& prometheus_metric : metric_family.metric) { - for (const auto& label : prometheus_metric.label) { - if (label.name == "metric_class") { - REQUIRE(ranges::find(valid_metrics_without_flow, label.value) != ranges::end(valid_metrics_without_flow)); - } - } + auto metric_class_label_it = ranges::find_if(prometheus_metric.label, [](const auto& label) { return label.name == "metric_class"; }); + REQUIRE(metric_class_label_it != ranges::end(prometheus_metric.label)); + REQUIRE(ranges::contains(valid_metrics_without_flow, metric_class_label_it->value)); + auto agent_identifier_label_it = ranges::find_if(prometheus_metric.label, [](const auto& label) { return label.name == "agent_identifier"; }); + REQUIRE(agent_identifier_label_it != ranges::end(prometheus_metric.label)); + REQUIRE(agent_identifier_label_it->value == "AgentId-1"); } } } diff --git a/libminifi/include/properties/Configuration.h b/libminifi/include/properties/Configuration.h index 906bdf0c2..7641aba4c 100644 --- a/libminifi/include/properties/Configuration.h +++ b/libminifi/include/properties/Configuration.h @@ -167,6 +167,7 @@ class Configuration : public Properties { static constexpr const char *nifi_asset_directory = "nifi.asset.directory"; // Metrics publisher options + static constexpr const char *nifi_metrics_publisher_agent_identifier = "nifi.metrics.publisher.agent.identifier"; static constexpr const char *nifi_metrics_publisher_class = "nifi.metrics.publisher.class"; static constexpr const char *nifi_metrics_publisher_prometheus_metrics_publisher_port = "nifi.metrics.publisher.PrometheusMetricsPublisher.port"; static constexpr const char *nifi_metrics_publisher_metrics = "nifi.metrics.publisher.metrics"; diff --git a/libminifi/include/utils/OsUtils.h b/libminifi/include/utils/OsUtils.h index a9b6253d3..66c9ea85c 100644 --- a/libminifi/include/utils/OsUtils.h +++ b/libminifi/include/utils/OsUtils.h @@ -14,20 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef LIBMINIFI_INCLUDE_UTILS_OSUTILS_H_ -#define LIBMINIFI_INCLUDE_UTILS_OSUTILS_H_ +#pragma once #include <string> +#include <optional> struct sockaddr; -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace utils { -namespace OsUtils { - +namespace org::apache::nifi::minifi::utils::OsUtils { /// Resolves a user ID to a username extern std::string userIdToUsername(const std::string &uid); @@ -54,12 +48,6 @@ std::string getMachineArchitecture(); extern std::string resolve_common_identifiers(const std::string &id); #endif +std::optional<std::string> getHostName(); -} /* namespace OsUtils */ -} /* namespace utils */ -} /* namespace minifi */ -} /* namespace nifi */ -} /* namespace apache */ -} /* namespace org */ - -#endif // LIBMINIFI_INCLUDE_UTILS_OSUTILS_H_ +} // namespace org::apache::nifi::minifi::utils::OsUtils diff --git a/libminifi/src/Configuration.cpp b/libminifi/src/Configuration.cpp index ccd8fcab9..5da28f49d 100644 --- a/libminifi/src/Configuration.cpp +++ b/libminifi/src/Configuration.cpp @@ -133,6 +133,7 @@ const std::vector<core::ConfigurationProperty> Configuration::CONFIGURATION_PROP core::ConfigurationProperty{Configuration::nifi_log_alert_buffer_limit}, core::ConfigurationProperty{Configuration::nifi_log_alert_level}, core::ConfigurationProperty{Configuration::nifi_asset_directory}, + core::ConfigurationProperty{Configuration::nifi_metrics_publisher_agent_identifier}, core::ConfigurationProperty{Configuration::nifi_metrics_publisher_class}, core::ConfigurationProperty{Configuration::nifi_metrics_publisher_prometheus_metrics_publisher_port, gsl::make_not_null(core::StandardValidators::get().PORT_VALIDATOR.get())}, core::ConfigurationProperty{Configuration::nifi_metrics_publisher_metrics} diff --git a/libminifi/src/utils/OsUtils.cpp b/libminifi/src/utils/OsUtils.cpp index cfac877d3..fd6789bc1 100644 --- a/libminifi/src/utils/OsUtils.cpp +++ b/libminifi/src/utils/OsUtils.cpp @@ -57,11 +57,7 @@ #include <sys/sysctl.h> #endif -namespace org { -namespace apache { -namespace nifi { -namespace minifi { -namespace utils { +namespace org::apache::nifi::minifi::utils { #ifdef _WIN32 /* @@ -320,9 +316,13 @@ std::string OsUtils::getMachineArchitecture() { return "unknown"; } -} // namespace utils -} // namespace minifi -} // namespace nifi -} // namespace apache -} // namespace org +std::optional<std::string> OsUtils::getHostName() { + char hostname[1024]; + hostname[1023] = '\0'; + if (gethostname(hostname, 1023) != 0) { + return std::nullopt; + } + return {hostname}; +} +} // namespace org::apache::nifi::minifi::utils diff --git a/libminifi/test/resources/encrypted.minifi.properties b/libminifi/test/resources/encrypted.minifi.properties index 11c38e182..920034036 100644 --- a/libminifi/test/resources/encrypted.minifi.properties +++ b/libminifi/test/resources/encrypted.minifi.properties @@ -104,6 +104,7 @@ nifi.c2.flow.url= nifi.sensitive.props.additional.keys=c2.agent.identifier # Publish metrics to external consumers +# nifi.metrics.publisher.agent.identifier= # nifi.metrics.publisher.class=PrometheusMetricsPublisher # nifi.metrics.publisher.PrometheusMetricsPublisher.port=9936 # nifi.metrics.publisher.metrics=QueueMetrics,RepositoryMetrics,GetFileMetrics,DeviceInfoNode,FlowInformation
