diff --git a/src/v/cluster/metrics_reporter.cc b/src/v/cluster/metrics_reporter.cc index 019f97964ad34..f9f30481301ba 100644 --- a/src/v/cluster/metrics_reporter.cc +++ b/src/v/cluster/metrics_reporter.cc @@ -43,7 +43,9 @@ #include #include #include +#include #include +#include #include #include @@ -53,9 +55,38 @@ #include #include #include +#include +#include +#include #include +namespace { +ss::sstring get_hostname() { + std::array hostname{}; + if (::gethostname(hostname.data(), hostname.size()) != 0) { + return {}; + } + + return hostname.data(); +} + +ss::sstring get_domainname() { + std::array domainname{}; + if (::getdomainname(domainname.data(), domainname.size()) != 0) { + return {}; + } + + return domainname.data(); +} + +ss::future> get_fqdns(std::string_view hostname) { + ss::net::dns_resolver resolver; + auto hostent = co_await resolver.get_host_by_name(hostname.data()); + co_return hostent.names; +} +} // namespace + namespace cluster { namespace details { @@ -217,6 +248,14 @@ metrics_reporter::build_metrics_snapshot() { } metrics.uptime_ms = report->local_state.uptime / 1ms; + auto& advertised_listeners + = nm->get().broker.kafka_advertised_listeners(); + metrics.advertised_listeners.reserve(advertised_listeners.size()); + std::transform( + advertised_listeners.begin(), + advertised_listeners.end(), + std::back_inserter(metrics.advertised_listeners), + [](const model::broker_endpoint& ep) { return ep.address; }); } auto& topics = _topics.local().topics_map(); snapshot.topic_count = 0; @@ -276,6 +315,10 @@ metrics_reporter::build_metrics_snapshot() { snapshot.enterprise_features.emplace(std::move(feature_report)); + snapshot.host_name = get_hostname(); + snapshot.domain_name = get_domainname(); + snapshot.fqdns = co_await get_fqdns(snapshot.host_name); + co_return snapshot; } @@ -561,6 +604,15 @@ void rjson_serialize( w.EndArray(); } + w.Key("hostname"); + w.String(snapshot.host_name); + + w.Key("domainname"); + w.String(snapshot.domain_name); + + w.Key("fqdns"); + rjson_serialize(w, snapshot.fqdns); + w.EndObject(); } @@ -597,6 +649,8 @@ void rjson_serialize( rjson_serialize(w, d); } w.EndArray(); + w.Key("kafka_advertised_listeners"); + rjson_serialize(w, nm.advertised_listeners); w.EndObject(); } diff --git a/src/v/cluster/metrics_reporter.h b/src/v/cluster/metrics_reporter.h index fdef6429f66cf..bb67472304ef9 100644 --- a/src/v/cluster/metrics_reporter.h +++ b/src/v/cluster/metrics_reporter.h @@ -20,6 +20,7 @@ #include "model/metadata.h" #include "security/fwd.h" #include "utils/prefix_logger.h" +#include "utils/unresolved_address.h" #include #include @@ -58,6 +59,7 @@ class metrics_reporter { cluster_version logical_version{invalid_version}; std::vector disks; uint64_t uptime_ms{0}; + std::vector advertised_listeners; }; struct metrics_snapshot { @@ -85,6 +87,10 @@ class metrics_reporter { bool has_valid_license{false}; std::optional enterprise_features; + + ss::sstring host_name; + ss::sstring domain_name; + std::vector fqdns; }; static constexpr ss::shard_id shard = 0; diff --git a/tests/rptest/tests/metrics_reporter_test.py b/tests/rptest/tests/metrics_reporter_test.py index 0066d1f26dff6..fa146c55360e6 100644 --- a/tests/rptest/tests/metrics_reporter_test.py +++ b/tests/rptest/tests/metrics_reporter_test.py @@ -138,6 +138,9 @@ def assert_fields_are_the_same(metadata, field): assert_fields_are_the_same(metadata, 'has_valid_license') assert_fields_are_the_same(metadata, 'has_enterprise_features') assert_fields_are_the_same(metadata, 'enterprise_features') + assert_fields_are_the_same(metadata, 'hostname') + assert_fields_are_the_same(metadata, 'domainname') + assert_fields_are_the_same(metadata, 'fqdns') # get the last report last = metadata.pop() assert last['topic_count'] == total_topics @@ -154,6 +157,9 @@ def assert_fields_are_the_same(metadata, field): assert 'has_enterprise_features' in last assert 'enterprise_features' in last assert type(last['enterprise_features']) == list + assert 'hostname' in last + assert 'domainname' in last + assert 'fqdns' in last nodes_meta = last['nodes'] assert len(last['nodes']) == len(self.redpanda.nodes) @@ -165,6 +171,7 @@ def assert_fields_are_the_same(metadata, field): assert all('uptime_ms' in n for n in nodes_meta) assert all('is_alive' in n for n in nodes_meta) assert all('disks' in n for n in nodes_meta) + assert all('kafka_advertised_listeners' in n for n in nodes_meta) # Check cluster UUID and creation time survive a restart for n in self.redpanda.nodes: