]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
exporter: exporter dir and http_server.h
authorPere Diaz Bou <pdiazbou@redhat.com>
Wed, 16 Mar 2022 12:26:46 +0000 (13:26 +0100)
committerAvan Thakkar <athakkar@redhat.com>
Mon, 20 Jun 2022 18:20:46 +0000 (23:50 +0530)
* move all related files to the exporter to src/exporter
* move http_server logic to a new file under src/exporter/http_server.*

Signed-off-by: Pere Diaz Bou <pdiazbou@redhat.com>
12 files changed:
src/CMakeLists.txt
src/ceph_exporter.cc
src/exporter/CMakeLists.txt [new file with mode: 0644]
src/exporter/DaemonMetricCollector.cc [new file with mode: 0644]
src/exporter/DaemonMetricCollector.h [new file with mode: 0644]
src/exporter/http_server.cc [new file with mode: 0644]
src/exporter/http_server.h [new file with mode: 0644]
src/mgr/CMakeLists.txt
src/mgr/DaemonMetricCollector.cc [deleted file]
src/mgr/DaemonMetricCollector.h [deleted file]
src/pybind/mgr/CMakeLists.txt
src/vstart.sh

index 2f608722099ba7ec8534be8424496261c05702e9..736510c4b230d70ac12906f14c611471f32707e4 100644 (file)
@@ -597,6 +597,7 @@ endif(NOT WITH_SYSTEM_ROCKSDB)
 
 if(WITH_MGR)
   add_subdirectory(mgr)
+  add_subdirectory(exporter)
 endif()
 
 set(librados_config_srcs
@@ -907,6 +908,7 @@ endif()
 
 if (WITH_MGR)
   add_dependencies(vstart-base ceph-mgr)
+  add_dependencies(vstart-base ceph-exporter)
 endif()
 
 add_custom_target(vstart DEPENDS vstart-base)
index 37e33bdad62d1d39b459ac04b998d8439ae2432b..4406828b3bb056540d6f36ced260e987864a1bc6 100644 (file)
-#include "mgr/DaemonMetricCollector.h"
+#include "exporter/DaemonMetricCollector.h"
+#include "exporter/http_server.h"
 #include <iostream>
-#include "global/global_init.h"
-#include "common/ceph_argparse.h"
-#include "common/hostname.h"
 #include <map>
-#include <boost/beast/core.hpp>
-#include <boost/beast/http.hpp>
-#include <boost/beast/version.hpp>
-#include <boost/asio.hpp>
-#include <chrono>
-#include <cstdlib>
-#include <ctime>
 #include <iostream>
-#include <memory>
 #include <string>
 #include <boost/thread/thread.hpp>
 
 
 
-namespace beast = boost::beast;         // from <boost/beast.hpp>
-namespace http = beast::http;           // from <boost/beast/http.hpp>
-namespace net = boost::asio;            // from <boost/asio.hpp>
-using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
-
 // FIXME: lets save collector instance here for now.
 DaemonMetricCollector collector;
 
-namespace my_program_state
-{
-    std::size_t
-    request_count()
-    {
-        static std::size_t count = 0;
-        return ++count;
-    }
-
-    std::time_t
-    now()
-    {
-        return std::time(0);
-    }
-}
-
-class http_connection : public std::enable_shared_from_this<http_connection>
-{
-public:
-    http_connection(tcp::socket socket)
-        : socket_(std::move(socket))
-    {
-    }
-
-    // Initiate the asynchronous operations associated with the connection.
-    void start()
-    {
-        read_request();
-        check_deadline();
-    }
-
-private:
-    tcp::socket socket_;
-    beast::flat_buffer buffer_{8192};
-    http::request<http::dynamic_body> request_;
-    http::response<http::dynamic_body> response_;
-
-    net::steady_timer deadline_{
-        socket_.get_executor(), std::chrono::seconds(60)};
-
-    // Asynchronously receive a complete request message.
-    void read_request()
-    {
-        // auto self = shared_from_this();
-
-        http::async_read(
-            socket_,
-            buffer_,
-            request_,
-            [&](beast::error_code ec,
-                std::size_t bytes_transferred)
-            {
-                boost::ignore_unused(bytes_transferred);
-                if(!ec)
-                    process_request();
-            });
-    }
-
-    // Determine what needs to be done with the request message.
-    void process_request()
-    {
-        response_.version(request_.version());
-        response_.keep_alive(false);
-
-        switch(request_.method())
-        {
-        case http::verb::get:
-            response_.result(http::status::ok);
-            response_.set(http::field::server, "Beast");
-            create_response();
-            break;
-
-        default:
-            // We return responses indicating an error if
-            // we do not recognize the request method.
-            response_.result(http::status::bad_request);
-            response_.set(http::field::content_type, "text/plain");
-            beast::ostream(response_.body())
-                << "Invalid request-method '"
-                << std::string(request_.method_string())
-                << "'";
-            break;
-        }
-
-        write_response();
-    }
-
-    // Construct a response message based on the program state.
-    void create_response()
-    {
-        std::cout << "Got request on " << request_.target() << std::endl;
-        if(request_.target() == "/perf_counters")
-        {
-            response_.set(http::field::content_type, "text/plain");
-            std::string metrics = collector.get_metrics();
-            beast::ostream(response_.body()) << "Perf Counters\n" << metrics << std::endl;
-        }
-        else
-        {
-            response_.result(http::status::not_found);
-            response_.set(http::field::content_type, "text/plain");
-            beast::ostream(response_.body()) << "File not found\r\n";
-        }
-    }
-
-    // Asynchronously transmit the response message.
-    void write_response()
-    {
-        auto self = shared_from_this();
-
-        response_.content_length(response_.body().size());
-
-        http::async_write(
-            socket_,
-            response_,
-            [self](beast::error_code ec, std::size_t)
-            {
-                self->socket_.shutdown(tcp::socket::shutdown_send, ec);
-                self->deadline_.cancel();
-            });
-    }
-
-    // Check whether we have spent enough time on this connection.
-    void check_deadline()
-    {
-        auto self = shared_from_this();
-
-        deadline_.async_wait(
-            [self](beast::error_code ec)
-            {
-                if(!ec)
-                {
-                    // Close socket to cancel any outstanding operation.
-                    self->socket_.close(ec);
-                }
-            });
-    }
-};
-
-// "Loop" forever accepting new connections.
-void http_server(tcp::acceptor& acceptor, tcp::socket& socket)
-{
-  acceptor.async_accept(socket,
-      [&](beast::error_code ec)
-      {
-          std::cout << "async accept" << std::endl;
-          if(!ec)
-              std::make_shared<http_connection>(std::move(socket))->start();
-          http_server(acceptor, socket);
-      });
-}
-
-std::string dns_lookup(std::string hostname) {
-    boost::asio::io_service io_service;
-    boost::asio::ip::tcp::resolver resolver(io_service);
-    boost::asio::ip::tcp::resolver::query query(hostname, "9085");
-    boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query);
-    boost::asio::ip::tcp::endpoint endpoint = iter->endpoint();
-    std::string ip_address = endpoint.address().to_string();
-
-    return ip_address;
-}
-
-void http_server_thread_entrypoint() {
-  try
-    {
-        std::string hostname = ceph_get_short_hostname();
-
-        std::string ip_address = dns_lookup(hostname);
-        auto const address = net::ip::make_address(ip_address);
-        unsigned short port = static_cast<unsigned short>(std::atoi("9085"));
-
-        net::io_context ioc{1};
-
-        tcp::acceptor acceptor{ioc, {address, port}};
-        tcp::socket socket{ioc};
-        http_server(acceptor, socket);
-        std::cout << "Http server started" << std::endl;
-        ioc.run();
-    }
-    catch(std::exception const& e)
-    {
-        std::cerr << "Error: " << e.what() << std::endl;
-        exit(EXIT_FAILURE);
-    }
-}
 
 int main(int argc, char** argv) {
   // TODO: daemonize
@@ -220,6 +19,7 @@ int main(int argc, char** argv) {
   std::cout << "Starting http server thread..." << std::endl;
   boost::thread server_thread(http_server_thread_entrypoint);
   std::cout << "Starting collector..." << std::endl;
+  DaemonMetricCollector &collector = collector_instance();
   collector.main();
   server_thread.join();
 }
diff --git a/src/exporter/CMakeLists.txt b/src/exporter/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ba06295
--- /dev/null
@@ -0,0 +1,8 @@
+set(exporter_srcs
+  ${CMAKE_SOURCE_DIR}/src/ceph_exporter.cc
+  DaemonMetricCollector.cc
+  http_server.cc
+  )
+add_executable(ceph-exporter ${exporter_srcs})
+target_link_libraries(ceph-exporter
+  global-static ceph-common)
diff --git a/src/exporter/DaemonMetricCollector.cc b/src/exporter/DaemonMetricCollector.cc
new file mode 100644 (file)
index 0000000..c50b0ed
--- /dev/null
@@ -0,0 +1,160 @@
+#include "DaemonMetricCollector.h"
+#include "common/admin_socket_client.h"
+#include "include/common_fwd.h"
+#include "common/perf_counters.h"
+
+#include <string>
+#include <iostream>
+#include <filesystem>
+#include <regex>
+#include <boost/json/src.hpp>
+
+using json_object = boost::json::object;
+using json_value = boost::json::value;
+using json_array = boost::json::array;
+
+void DaemonMetricCollector::request_loop(boost::asio::deadline_timer &timer) {
+  timer.async_wait([&](const boost::system::error_code& e) {
+    std::cerr << e << std::endl;
+    update_sockets();
+    std::cout << "updating metrics" << std::endl;
+    send_requests();
+    timer.expires_from_now(boost::posix_time::seconds(stats_period));
+    request_loop(timer);
+  });
+}
+
+void DaemonMetricCollector::main() {
+  stats_period = 5; // TODO: let's do 5 for now and expose this to change in the future
+  boost::asio::io_service io;
+  boost::asio::deadline_timer timer(io, boost::posix_time::seconds(stats_period));
+  request_loop(timer);
+  io.run();
+}
+
+std::string DaemonMetricCollector::get_metrics() {
+  return metrics;
+}
+
+template <class T>
+void add_metric(std::stringstream &ss, T value, std::string name, std::string description,
+                                       std::string mtype, std::string labels) {
+  ss << "# HELP " << name << " " << description << "\n";
+  ss << "# TYPE " << name << " " << mtype << "\n";
+  ss << name << "{" << labels << "} " << value << "\n";
+}
+
+void add_double_or_int_metric(std::stringstream &ss, json_value value, std::string name, std::string description,
+                                                     std::string mtype, std::string labels) {
+  if (value.is_int64()) {
+    int64_t v = value.as_int64();
+    add_metric(ss, v, name, description, mtype, labels);
+  }
+  else if (value.is_double()) {
+    double v = value.as_double();
+    add_metric(ss, v, name, description, mtype, labels);
+  }
+}
+
+std::string boost_string_to_std(boost::json::string js) {
+  std::string res(js.data());
+  return res;
+}
+
+void DaemonMetricCollector::send_requests() {
+  std::string result;
+  for(auto client : clients) {
+    AdminSocketClient &sock_client = client.second;
+    std::string daemon_name = client.first;
+    std::string request("{\"prefix\":\"perf dump\"}");
+    std::string response;
+    sock_client.do_request(request, &response);
+    if (response.size() > 0) {
+      json_object dump = boost::json::parse(response).as_object();
+      request = "{\"prefix\":\"perf schema\"}";
+      response = "";
+      sock_client.do_request(request, &response);
+      json_object schema = boost::json::parse(response).as_object();
+      for (auto perf : schema) {
+        std::string perf_group = perf.key().to_string();
+        json_object perf_group_object = perf.value().as_object();
+        for (auto perf_counter : perf_group_object) {
+          std::string perf_name = perf_counter.key().to_string();
+          json_object perf_info = perf_counter.value().as_object();
+          if (perf_info["priority"].as_int64() < PerfCountersBuilder::PRIO_USEFUL) {
+            continue;
+          }
+          int64_t type = perf_info["type"].as_int64();
+          std::string mtype = boost_string_to_std(perf_info["metric_type"].as_string());
+          std::string description = boost_string_to_std(perf_info["description"].as_string());
+          std::stringstream ss;
+          std::string name = "ceph_" + perf_group + "_" + perf_name;
+
+          std::string labels;
+          // Labels
+          // FIXME: test this, based on mgr_module perfpath_to_path_labels
+          if (daemon_name.substr(0, 4) == "rgw.") {
+            labels = "instance_id=" + daemon_name.substr(4, std::string::npos);
+          } else {
+            labels = "ceph_daemon=" + daemon_name;
+            if (daemon_name.substr(0, 11) == "rbd-mirror.") {
+              std::regex re("^rbd_mirror_image_([^/]+)/(?:(?:([^/]+)/)?)(.*)\\.(replay(?:_bytes|_latency)?)$");
+              std::smatch match;
+              if (std::regex_search(daemon_name, match, re) == true) {
+                name = "ceph_rbd_mirror_image_" + match.str(4);
+                labels += ",pool=" + match.str(1);
+                labels += ",namespace=" + match.str(2);
+                labels += ",image=" + match.str(3);
+              }
+            }
+          }
+
+          // value and add_metric
+          json_value perf_values = dump[perf_group].as_object()[perf_name];
+          if (type & PERFCOUNTER_LONGRUNAVG) {
+            int64_t count = perf_values.as_object()["avgcount"].as_int64();
+            add_metric(ss, count, name + "_count", description, mtype, labels);
+            json_value sum_value = perf_values.as_object()["sum"];
+            add_double_or_int_metric(ss, sum_value, name + "_sum", description, mtype, labels);
+          } else if(type & PERFCOUNTER_TIME) {
+            if (perf_values.is_int64()) {
+              double value = perf_values.as_int64() / 1000000000.0f;
+              add_metric(ss, value, name, description, mtype, labels);
+            }
+            else if (perf_values.is_double()) {
+              double value = perf_values.as_double() / 1000000000.0f;
+              add_metric(ss, value, name, description, mtype, labels);
+            }
+          } else {
+            add_double_or_int_metric(ss, perf_values, name, description, mtype, labels);
+          }
+          result += ss.str() + "\n";
+        }
+      }
+    }
+  }
+  metrics = result;
+}
+
+void DaemonMetricCollector::update_sockets() {
+  std::string path = "/tmp/ceph-asok.Qq4nS2";
+  for (const auto & entry : std::filesystem::directory_iterator(path)) {
+    std::string daemon_socket_name = entry.path().filename().string();
+    std::cout << "Got socket: " << daemon_socket_name << std::endl;
+    // remove .asok
+    std::string daemon_name = daemon_socket_name.substr(0, daemon_socket_name.size() - 5);
+    if (clients.find(daemon_name) == clients.end()) {
+      AdminSocketClient sock(entry.path().string());
+      clients.insert({daemon_name, std::move(sock)});
+    }
+  }
+}
+
+DaemonMetricCollector *_collector_instance = nullptr;
+
+DaemonMetricCollector& collector_instance() {
+  if (_collector_instance == nullptr) {
+    _collector_instance = new DaemonMetricCollector();
+  }
+  return *_collector_instance;
+}
diff --git a/src/exporter/DaemonMetricCollector.h b/src/exporter/DaemonMetricCollector.h
new file mode 100644 (file)
index 0000000..31d34aa
--- /dev/null
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "common/admin_socket_client.h"
+#include <string>
+#include <map>
+#include <vector>
+
+#include <string>
+#include <map>
+#include <vector>
+#include <boost/asio.hpp>
+
+class DaemonMetricCollector {
+ public:
+  int i;
+  void main();
+  std::string get_metrics();
+
+private:
+  // TODO: add clients
+  //       check removed sockets
+  //       list dir of sockets
+  std::map<std::string, AdminSocketClient> clients;
+  std::string metrics;
+  int stats_period; // time to wait before sending requests again
+  void update_sockets();
+  void request_loop(boost::asio::deadline_timer &timer);
+  void send_requests();
+  void start_mgr_connection();
+};
+
+DaemonMetricCollector& collector_instance();
diff --git a/src/exporter/http_server.cc b/src/exporter/http_server.cc
new file mode 100644 (file)
index 0000000..b3db4d3
--- /dev/null
@@ -0,0 +1,210 @@
+#include "http_server.h"
+#include "exporter/DaemonMetricCollector.h"
+#include "common/hostname.h"
+
+#include <iostream>
+#include <map>
+#include <boost/beast/core.hpp>
+#include <boost/beast/http.hpp>
+#include <boost/beast/version.hpp>
+#include <boost/asio.hpp>
+#include <chrono>
+#include <cstdlib>
+#include <ctime>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <boost/thread/thread.hpp>
+
+namespace beast = boost::beast;         // from <boost/beast.hpp>
+namespace http = beast::http;           // from <boost/beast/http.hpp>
+namespace net = boost::asio;            // from <boost/asio.hpp>
+using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
+
+namespace my_program_state
+{
+    std::size_t
+    request_count()
+    {
+        static std::size_t count = 0;
+        return ++count;
+    }
+
+    std::time_t
+    now()
+    {
+        return std::time(0);
+    }
+}
+
+class http_connection : public std::enable_shared_from_this<http_connection>
+{
+public:
+    http_connection(tcp::socket socket)
+        : socket_(std::move(socket))
+    {
+    }
+
+    // Initiate the asynchronous operations associated with the connection.
+    void start()
+    {
+        read_request();
+        check_deadline();
+    }
+
+private:
+    tcp::socket socket_;
+    beast::flat_buffer buffer_{8192};
+    http::request<http::dynamic_body> request_;
+    http::response<http::dynamic_body> response_;
+
+    net::steady_timer deadline_{
+        socket_.get_executor(), std::chrono::seconds(60)};
+
+    // Asynchronously receive a complete request message.
+    void read_request()
+    {
+        // auto self = shared_from_this();
+
+        http::async_read(
+            socket_,
+            buffer_,
+            request_,
+            [&](beast::error_code ec,
+                std::size_t bytes_transferred)
+            {
+                boost::ignore_unused(bytes_transferred);
+                if(!ec)
+                    process_request();
+            });
+    }
+
+    // Determine what needs to be done with the request message.
+    void process_request()
+    {
+        response_.version(request_.version());
+        response_.keep_alive(false);
+
+        switch(request_.method())
+        {
+        case http::verb::get:
+            response_.result(http::status::ok);
+            response_.set(http::field::server, "Beast");
+            create_response();
+            break;
+
+        default:
+            // We return responses indicating an error if
+            // we do not recognize the request method.
+            response_.result(http::status::bad_request);
+            response_.set(http::field::content_type, "text/plain");
+            beast::ostream(response_.body())
+                << "Invalid request-method '"
+                << std::string(request_.method_string())
+                << "'";
+            break;
+        }
+
+        write_response();
+    }
+
+    // Construct a response message based on the program state.
+    void create_response()
+    {
+        std::cout << "Got request on " << request_.target() << std::endl;
+        if(request_.target() == "/metrics")
+        {
+            response_.set(http::field::content_type, "text/plain");
+            DaemonMetricCollector &collector = collector_instance();
+            std::string metrics = collector.get_metrics();
+            beast::ostream(response_.body()) << "Perf Counters\n" << metrics << std::endl;
+        }
+        else
+        {
+            response_.result(http::status::not_found);
+            response_.set(http::field::content_type, "text/plain");
+            beast::ostream(response_.body()) << "File not found\r\n";
+        }
+    }
+
+    // Asynchronously transmit the response message.
+    void write_response()
+    {
+        auto self = shared_from_this();
+
+        response_.content_length(response_.body().size());
+
+        http::async_write(
+            socket_,
+            response_,
+            [self](beast::error_code ec, std::size_t)
+            {
+                self->socket_.shutdown(tcp::socket::shutdown_send, ec);
+                self->deadline_.cancel();
+            });
+    }
+
+    // Check whether we have spent enough time on this connection.
+    void check_deadline()
+    {
+        auto self = shared_from_this();
+
+        deadline_.async_wait(
+            [self](beast::error_code ec)
+            {
+                if(!ec)
+                {
+                    // Close socket to cancel any outstanding operation.
+                    self->socket_.close(ec);
+                }
+            });
+    }
+};
+
+// "Loop" forever accepting new connections.
+void http_server(tcp::acceptor& acceptor, tcp::socket& socket)
+{
+  acceptor.async_accept(socket,
+      [&](beast::error_code ec)
+      {
+          std::cout << "async accept" << std::endl;
+          if(!ec)
+              std::make_shared<http_connection>(std::move(socket))->start();
+          http_server(acceptor, socket);
+      });
+}
+
+std::string dns_lookup(std::string hostname) {
+    boost::asio::io_service io_service;
+    boost::asio::ip::tcp::resolver resolver(io_service);
+    boost::asio::ip::tcp::resolver::query query(hostname, "9085");
+    boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query);
+    boost::asio::ip::tcp::endpoint endpoint = iter->endpoint();
+    std::string ip_address = endpoint.address().to_string();
+
+    return ip_address;
+}
+
+void http_server_thread_entrypoint() {
+  try
+    {
+        std::string hostname = ceph_get_short_hostname();
+
+        std::string ip_address = dns_lookup(hostname);
+        auto const address = net::ip::make_address(ip_address);
+        unsigned short port = static_cast<unsigned short>(std::atoi("9085"));
+
+        net::io_context ioc{1};
+
+        tcp::acceptor acceptor{ioc, {address, port}};
+        tcp::socket socket{ioc};
+        http_server(acceptor, socket);
+        std::cout << "Http server started" << std::endl;
+        ioc.run();
+    }
+    catch(std::exception const& e)
+    {
+        std::cerr << "Error: " << e.what() << std::endl;
+        exit(EXIT_FAILURE);
+    }
+}
diff --git a/src/exporter/http_server.h b/src/exporter/http_server.h
new file mode 100644 (file)
index 0000000..55e6190
--- /dev/null
@@ -0,0 +1,3 @@
+#pragma once
+
+void http_server_thread_entrypoint();
index 4f1003a6149a87462ea424a3cfbaaed6b95d8e22..f9ec04317f4be64fde5fe59af382a5b70d66bb9b 100644 (file)
@@ -33,14 +33,7 @@ if(WITH_MGR)
     StandbyPyModules.cc
     mgr_commands.cc
     $<TARGET_OBJECTS:mgr_cap_obj>)
-  set(exporter_srcs
-    ${CMAKE_SOURCE_DIR}/src/ceph_exporter.cc
-    DaemonMetricCollector.cc
-    )
   add_executable(ceph-mgr ${mgr_srcs})
-  add_executable(ceph-exporter ${exporter_srcs})
-  target_link_libraries(ceph-exporter
-    global-static ceph-common)
   target_compile_definitions(ceph-mgr PRIVATE PY_SSIZE_T_CLEAN)
   if(WITH_LIBCEPHSQLITE)
     target_link_libraries(ceph-mgr cephsqlite SQLite3::SQLite3)
diff --git a/src/mgr/DaemonMetricCollector.cc b/src/mgr/DaemonMetricCollector.cc
deleted file mode 100644 (file)
index 9a74359..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-#include "DaemonMetricCollector.h"
-#include "common/admin_socket_client.h"
-#include "include/common_fwd.h"
-#include "common/perf_counters.h"
-
-#include <string>
-#include <iostream>
-#include <filesystem>
-#include <regex>
-#include <boost/json/src.hpp>
-
-using json_object = boost::json::object;
-using json_value = boost::json::value;
-using json_array = boost::json::array;
-
-void DaemonMetricCollector::request_loop(boost::asio::deadline_timer &timer) {
-  timer.async_wait([&](const boost::system::error_code& e) {
-    std::cerr << e << std::endl;
-    update_sockets();
-    std::cout << "updating metrics" << std::endl;
-    send_requests();
-    timer.expires_from_now(boost::posix_time::seconds(stats_period));
-    request_loop(timer);
-  });
-}
-void DaemonMetricCollector::main() {
-  stats_period = 5; // TODO: let's do 5 for now and expose this to change in the future
-  boost::asio::io_service io;
-  boost::asio::deadline_timer timer(io, boost::posix_time::seconds(stats_period));
-  std::cout << "before request" << std::endl;
-  request_loop(timer);
-  io.run();
-}
-
-std::string DaemonMetricCollector::get_metrics() {
-  return metrics;
-}
-
-template <class T>
-void add_metric(std::stringstream &ss, T value, std::string name, std::string description,
-                                       std::string mtype, std::string labels) {
-  ss << "# HELP " << name << " " << description << "\n";
-  ss << "# TYPE " << name << " " << mtype << "\n";
-  ss << name << "{" << labels << "} " << value << "\n";
-}
-
-void add_double_or_int_metric(std::stringstream &ss, json_value value, std::string name, std::string description,
-                                                     std::string mtype, std::string labels) {
-  if (value.is_int64()) {
-    int64_t v = value.as_int64();
-    add_metric(ss, v, name, description, mtype, labels);
-  }
-  else if (value.is_double()) {
-    double v = value.as_double();
-    add_metric(ss, v, name, description, mtype, labels);
-  }
-}
-
-std::string boost_string_to_std(boost::json::string js) {
-  std::string res(js.data());
-  return res;
-}
-
-void DaemonMetricCollector::send_requests() {
-  std::string result;
-  for(auto client : clients) {
-    AdminSocketClient &sock_client = client.second;
-    std::string daemon_name = client.first;
-    std::string request("{\"prefix\":\"perf dump\"}");
-    std::string response;
-    sock_client.do_request(request, &response);
-    if (response.size() > 0) {
-      json_object dump = boost::json::parse(response).as_object();
-      request = "{\"prefix\":\"perf schema\"}";
-      response = "";
-      sock_client.do_request(request, &response);
-      json_object schema = boost::json::parse(response).as_object();
-      for (auto perf : schema) {
-        std::string perf_group = perf.key().to_string();
-        json_object perf_group_object = perf.value().as_object();
-        for (auto perf_counter : perf_group_object) {
-          std::string perf_name = perf_counter.key().to_string();
-          json_object perf_info = perf_counter.value().as_object();
-          if (perf_info["priority"].as_int64() < PerfCountersBuilder::PRIO_USEFUL) {
-            continue;
-          }
-          int64_t type = perf_info["type"].as_int64();
-          std::string mtype = boost_string_to_std(perf_info["metric_type"].as_string());
-          std::string description = boost_string_to_std(perf_info["description"].as_string());
-          std::stringstream ss;
-          std::string name = "ceph_" + perf_group + "_" + perf_name;
-
-          std::string labels;
-          // Labels
-          // FIXME: test this, based on mgr_module perfpath_to_path_labels
-          if (daemon_name.substr(0, 4) == "rgw.") {
-            labels = "instance_id=" + daemon_name.substr(4, std::string::npos);
-          } else {
-            labels = "ceph_daemon=" + daemon_name;
-            if (daemon_name.substr(0, 11) == "rbd-mirror.") {
-              std::regex re("^rbd_mirror_image_([^/]+)/(?:(?:([^/]+)/)?)(.*)\\.(replay(?:_bytes|_latency)?)$");
-              std::smatch match;
-              if (std::regex_search(daemon_name, match, re) == true) {
-                name = "ceph_rbd_mirror_image_" + match.str(4);
-                labels += ",pool=" + match.str(1);
-                labels += ",namespace=" + match.str(2);
-                labels += ",image=" + match.str(3);
-              }
-            }
-          }
-
-          // value and add_metric
-          json_value perf_values = dump[perf_group].as_object()[perf_name];
-          if (type & PERFCOUNTER_LONGRUNAVG) {
-            int64_t count = perf_values.as_object()["avgcount"].as_int64();
-            add_metric(ss, count, name + "_count", description, mtype, labels);
-            json_value sum_value = perf_values.as_object()["sum"];
-            add_double_or_int_metric(ss, sum_value, name + "_sum", description, mtype, labels);
-          } else if(type & PERFCOUNTER_TIME) {
-            if (perf_values.is_int64()) {
-              double value = perf_values.as_int64() / 1000000000.0f;
-              add_metric(ss, value, name, description, mtype, labels);
-            }
-            else if (perf_values.is_double()) {
-              double value = perf_values.as_double() / 1000000000.0f;
-              add_metric(ss, value, name, description, mtype, labels);
-            }
-          } else {
-            add_double_or_int_metric(ss, perf_values, name, description, mtype, labels);
-          }
-          result += ss.str() + "\n";
-        }
-      }
-    }
-  }
-  metrics = result;
-}
-
-void DaemonMetricCollector::update_sockets() {
-  std::string path = "/tmp/ceph-asok.7MK7oH/";
-  for (const auto & entry : std::filesystem::directory_iterator(path)) {
-    std::string daemon_socket_name = entry.path().filename().string();
-    // remove .asok
-    std::string daemon_name = daemon_socket_name.substr(0, daemon_socket_name.size() - 5);
-    if (clients.find(daemon_name) == clients.end()) {
-      AdminSocketClient sock(entry.path().string());
-      clients.insert({daemon_name, std::move(sock)});
-    }
-  }
-}
diff --git a/src/mgr/DaemonMetricCollector.h b/src/mgr/DaemonMetricCollector.h
deleted file mode 100644 (file)
index a9b6c81..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "common/admin_socket_client.h"
-#include <string>
-#include <map>
-#include <vector>
-
-#include <string>
-#include <map>
-#include <vector>
-#include <boost/asio.hpp>
-
-class DaemonMetricCollector {
- public:
-  int i;
-  void main();
-  std::string get_metrics();
-
-private:
-  // TODO: add clients
-  //       check removed sockets
-  //       list dir of sockets
-  std::map<std::string, AdminSocketClient> clients;
-  std::string metrics;
-  int stats_period; // time to wait before sending requests again
-  void update_sockets();
-  void request_loop(boost::asio::deadline_timer &timer);
-  void send_requests();
-  void start_mgr_connection();
-};
index d25254048a5c5840fe1e1501b5cd86196fc90981..54aa9142028927b5fd3d0ffa35a6133299f720e9 100644 (file)
@@ -8,9 +8,9 @@ set(mgr_module_install_excludes
 
 add_subdirectory(dashboard)
 
-if(WITH_MGR_ROOK_CLIENT)
-  add_subdirectory(rook)
-endif()
+if(WITH_MGR_ROOK_CLIENT)
+  add_subdirectory(rook)
+endif()
 if(WITH_TESTS)
   include(AddCephTest)
   add_tox_test(mgr ${CMAKE_CURRENT_SOURCE_DIR} TOX_ENVS py3 py37 mypy flake8 jinjalint nooptional)
index 4a9d0005230e55f0010d21f82b83ef2ce764d3c2..5518e300624fe7e167c3c868187bc86bbd716d09 100755 (executable)
@@ -788,6 +788,7 @@ $DAEMONOPTS
         mds root ino gid = `id -g`
         $(format_conf "${extra_conf}")
 [mgr]
+        mgr disabled modules = rook
         mgr data = $CEPH_DEV_DIR/mgr.\$id
         mgr module path = $MGR_PYTHON_PATH
         cephadm path = $CEPH_ROOT/src/cephadm/cephadm
@@ -822,7 +823,6 @@ $COSDSHORT
         $(format_conf "${extra_conf}")
 [mon]
         mon_data_avail_crit = 1
-        mgr disabled modules = rook
         mgr initial modules = $mgr_modules
 $DAEMONOPTS
 $CMONDEBUG