entrypoint = '/usr/bin/ceph-exporter'
port_map = {
- 'exporter': 9085,
+ 'exporter': 9926,
}
def __init__(self,
cli(['orch', 'apply', 'crash'])
if not ctx.skip_monitoring_stack:
- for t in ['prometheus', 'grafana', 'node-exporter', 'alertmanager']:
+ for t in ['exporter', 'prometheus', 'grafana', 'node-exporter', 'alertmanager']:
logger.info('Deploying %s service with default placement...' % t)
cli(['orch', 'apply', t])
std::string daemon_name = client.first;
std::string request("{\"prefix\":\"perf dump\"}");
std::string response;
- sock_client.do_request(request, &response);
+ try {
+ sock_client.do_request(request, &response);
+ }
+ catch (const std::exception& e) {
+ std::cout << "culprit: " << daemon_name << std::endl;
+ std::cerr << "Mission abort!!: " << e.what() << std::endl;
+ }
if (response.size() > 0) {
+ std::cout << "wow: " << daemon_name << std::endl;
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();
+ json_object schema = boost::json::parse(response).as_object();
+ std::cout << "nice: " << schema << std::endl;
for (auto perf : schema) {
std::string perf_group = perf.key().to_string();
json_object perf_group_object = perf.value().as_object();
std::string labels;
// Labels
// FIXME: test this, based on mgr_module perfpath_to_path_labels
- if (daemon_name.substr(0, 4) == "rgw.") {
+ if (daemon_name.find("rgw") != std::string::npos) {
+ std::cout << "rgw: " << daemon_name << std::endl;
labels = std::string("instance_id=") + quote(daemon_name.substr(4, std::string::npos));
} else {
labels = "ceph_daemon=" + quote(daemon_name);
- if (daemon_name.substr(0, 11) == "rbd-mirror.") {
+ if (daemon_name.find("rbd-mirror") != std::string::npos) {
std::regex re("^rbd_mirror_image_([^/]+)/(?:(?:([^/]+)/)?)(.*)\\.(replay(?:_bytes|_latency)?)$");
std::smatch match;
if (std::regex_search(daemon_name, match, re) == true) {
}
void DaemonMetricCollector::update_sockets() {
- std::string path = "/var/run/ceph/";
- for (const auto & entry : std::filesystem::recursive_directory_iterator(path)) {
+ for (const auto & entry : std::filesystem::recursive_directory_iterator(socketdir)) {
if (entry.path().extension() == ".asok") {
+ // std::cout << entry.path() << std::endl;
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()) {
+ if (clients.find(daemon_name) == clients.end() && !(daemon_name.find("mgr") != std::string::npos)) {
+ std::cout << "pathhh: " << entry.path().string() << std::endl;
AdminSocketClient sock(entry.path().string());
clients.insert({daemon_name, std::move(sock)});
}
#include <map>
#include <vector>
+#include<filesystem>
#include <string>
#include <map>
#include <vector>
#include <boost/asio.hpp>
+namespace fs = std::filesystem;
+
class DaemonMetricCollector {
public:
int i;
std::map<std::string, AdminSocketClient> clients;
std::string metrics;
int stats_period; // time to wait before sending requests again
+ fs::path socketdir = "/var/run/ceph/";
void update_sockets();
void request_loop(boost::asio::deadline_timer &timer);
void send_requests();
{
case http::verb::get:
response_.result(http::status::ok);
- response_.set(http::field::server, "Beast");
create_response();
break;
// Construct a response message based on the program state.
void create_response()
{
- if(request_.target() == "/metrics")
+ if (request_.target() == "/") {
+ response_.set(http::field::content_type, "text/html; charset=utf-8");
+ beast::ostream(response_.body())
+ << "<html>\n"
+ << "<head><title>Ceph Exporter</title></head>\n"
+ << "<body>\n"
+ << "<h1>Ceph Exporter</h1>\n"
+
+ << "<p><a href='/metrics'>Metrics</a></p>"
+ << "</body>\n"
+ << "</html>\n";
+ }
+ else if(request_.target() == "/metrics")
{
- response_.set(http::field::content_type, "text/plain");
+ response_.set(http::field::content_type, "text/plain; charset=utf-8");
DaemonMetricCollector &collector = collector_instance();
std::string metrics = collector.get_metrics();
beast::ostream(response_.body()) << metrics << std::endl;
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::query query(hostname, "9926");
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();
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"));
+ unsigned short port = static_cast<unsigned short>(std::atoi("9926"));
net::io_context ioc{1};
mgr_map = self.mgr.get('mgr_map')
port = cast(int, self.mgr.get_module_option_ex(
'prometheus', 'server_port', self.DEFAULT_MGR_PROMETHEUS_PORT))
+ exporter_port = 9926
deps.append(str(port))
t = mgr_map.get('services', {}).get('prometheus', None)
if t:
# append the brackets when building the final scrape endpoint
if '[' in p_result.netloc and ']' in p_result.netloc:
mgr_scrape_list.append(f"[{p_result.hostname}]:{port}")
+ mgr_scrape_list.append(f"[{p_result.hostname}]:{exporter_port}")
else:
mgr_scrape_list.append(f"{p_result.hostname}:{port}")
+ mgr_scrape_list.append(f"{p_result.hostname}:{exporter_port}")
+
# scan all mgrs to generate deps and to get standbys too.
# assume that they are all on the same port as the active mgr.
for dd in self.mgr.cache.get_daemons_by_service('mgr'):