if(WITH_MGR)
add_subdirectory(mgr)
+ add_subdirectory(exporter)
endif()
set(librados_config_srcs
if (WITH_MGR)
add_dependencies(vstart-base ceph-mgr)
+ add_dependencies(vstart-base ceph-exporter)
endif()
add_custom_target(vstart DEPENDS vstart-base)
-#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
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();
}
--- /dev/null
+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)
--- /dev/null
+#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;
+}
--- /dev/null
+#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();
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#pragma once
+
+void http_server_thread_entrypoint();
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)
+++ /dev/null
-#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)});
- }
- }
-}
+++ /dev/null
-#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();
-};
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)
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
$(format_conf "${extra_conf}")
[mon]
mon_data_avail_crit = 1
- mgr disabled modules = rook
mgr initial modules = $mgr_modules
$DAEMONOPTS
$CMONDEBUG