#include "common/ceph_argparse.h" #include "common/config.h" #include "common/debug.h" #include "global/global_init.h" #include "global/global_context.h" #include "global/signal_handler.h" #include "exporter/DaemonMetricCollector.h" #include "exporter/web_server.h" #include #include #include #include #include #include #include #define dout_context g_ceph_context #define dout_subsys ceph_subsys_ceph_exporter DaemonMetricCollector &collector = collector_instance(); static void handle_signal(int signum) { ceph_assert(signum == SIGINT || signum == SIGTERM); derr << "*** Got signal " << sig_str(signum) << " ***" << dendl; // Finish the DaemonMetricCollector collector.shutdown(); } static void usage() { std::cout << "usage: ceph-exporter [options]\n" << "options:\n" " --sock-dir: The path to Ceph daemon sockets (*.asok)\n" " --addrs: Host IP address on which the exporter is to listen\n" " --port: TCP Port on which the exporter is to listen. Default is 9926\n" " --cert-file: Path to the certificate file when using HTTPS\n" " --key-file: Path to the certificate key file when using HTTPS\n" " --prio-limit: Only perf counters greater than or equal to prio-limit are fetched. Default: 5\n" " --stats-period: Interval between daemon scrapes (seconds). Default: 5s" << std::endl; generic_server_usage(); } int main(int argc, char **argv) { auto args = argv_to_vec(argc, argv); if (args.empty()) { std::cerr << argv[0] << ": -h or --help for usage" << std::endl; exit(1); } if (ceph_argparse_need_usage(args)) { usage(); exit(0); } auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON, 0); std::string val; for (auto i = args.begin(); i != args.end();) { if (ceph_argparse_double_dash(args, i)) { break; } else if (ceph_argparse_witharg(args, i, &val, "--sock-dir", (char *)NULL)) { cct->_conf.set_val("exporter_sock_dir", val); } else if (ceph_argparse_witharg(args, i, &val, "--addrs", (char *)NULL)) { cct->_conf.set_val("exporter_addr", val); } else if (ceph_argparse_witharg(args, i, &val, "--port", (char *)NULL)) { cct->_conf.set_val("exporter_http_port", val); } else if (ceph_argparse_witharg(args, i, &val, "--cert-file", (char *)NULL)) { cct->_conf.set_val("exporter_cert_file", val); } else if (ceph_argparse_witharg(args, i, &val, "--key-file", (char *)NULL)) { cct->_conf.set_val("exporter_key_file", val); } else if (ceph_argparse_witharg(args, i, &val, "--prio-limit", (char *)NULL)) { cct->_conf.set_val("exporter_prio_limit", val); } else if (ceph_argparse_witharg(args, i, &val, "--stats-period", (char *)NULL)) { cct->_conf.set_val("exporter_stats_period", val); } else { ++i; } } common_init_finish(g_ceph_context); // Register signal handlers init_async_signal_handler(); register_async_signal_handler(SIGHUP, sighup_handler); register_async_signal_handler_oneshot(SIGINT, handle_signal); register_async_signal_handler_oneshot(SIGTERM, handle_signal); // Start the web server thread boost::thread server_thread(web_server_thread_entrypoint); // Start the DaemonMetricCollector collector.main(); // Interrupted. Time to terminate unregister_async_signal_handler(SIGHUP, sighup_handler); unregister_async_signal_handler(SIGINT, handle_signal); unregister_async_signal_handler(SIGTERM, handle_signal); shutdown_async_signal_handler(); // Stop the web server thread by interrupting it stop_web_server(); server_thread.interrupt(); // Interrupt the web server thread server_thread.join(); dout(1) << "Ceph exporter stopped" << dendl; return 0; }