| 1 | #include <iostream> | 
|---|
| 2 |  | 
|---|
| 3 | #include <boost/program_options.hpp> | 
|---|
| 4 | #include <Poco/Logger.h> | 
|---|
| 5 | #include <Poco/ConsoleChannel.h> | 
|---|
| 6 | #include <Poco/FormattingChannel.h> | 
|---|
| 7 | #include <Poco/PatternFormatter.h> | 
|---|
| 8 | #include <Poco/AutoPtr.h> | 
|---|
| 9 | #include <Poco/Util/XMLConfiguration.h> | 
|---|
| 10 |  | 
|---|
| 11 | #include <Common/ZooKeeper/ZooKeeperNodeCache.h> | 
|---|
| 12 | #include <Common/Config/ConfigProcessor.h> | 
|---|
| 13 | #include <Common/Exception.h> | 
|---|
| 14 |  | 
|---|
| 15 |  | 
|---|
| 16 | static void setupLogging(const std::string & log_level) | 
|---|
| 17 | { | 
|---|
| 18 | Poco::AutoPtr<Poco::ConsoleChannel> channel(new Poco::ConsoleChannel); | 
|---|
| 19 | Poco::AutoPtr<Poco::PatternFormatter> formatter(new Poco::PatternFormatter); | 
|---|
| 20 | formatter->setProperty( "pattern", "%L%Y-%m-%d %H:%M:%S.%i <%p> %s: %t"); | 
|---|
| 21 | Poco::AutoPtr<Poco::FormattingChannel> formatting_channel(new Poco::FormattingChannel(formatter, channel)); | 
|---|
| 22 | Poco::Logger::root().setChannel(formatting_channel); | 
|---|
| 23 | Poco::Logger::root().setLevel(log_level); | 
|---|
| 24 | } | 
|---|
| 25 |  | 
|---|
| 26 | static std::string ( | 
|---|
| 27 | const std::string & config_path, const std::string & key, bool process_zk_includes, bool try_get = false) | 
|---|
| 28 | { | 
|---|
| 29 | DB::ConfigProcessor processor(config_path, /* throw_on_bad_incl = */ false, /* log_to_console = */ false); | 
|---|
| 30 | bool has_zk_includes; | 
|---|
| 31 | DB::XMLDocumentPtr config_xml = processor.processConfig(&has_zk_includes); | 
|---|
| 32 | if (has_zk_includes && process_zk_includes) | 
|---|
| 33 | { | 
|---|
| 34 | DB::ConfigurationPtr bootstrap_configuration(new Poco::Util::XMLConfiguration(config_xml)); | 
|---|
| 35 | zkutil::ZooKeeperPtr zookeeper = std::make_shared<zkutil::ZooKeeper>( | 
|---|
| 36 | *bootstrap_configuration, "zookeeper"); | 
|---|
| 37 | zkutil::ZooKeeperNodeCache zk_node_cache([&] { return zookeeper; }); | 
|---|
| 38 | config_xml = processor.processConfig(&has_zk_includes, &zk_node_cache); | 
|---|
| 39 | } | 
|---|
| 40 | DB::ConfigurationPtr configuration(new Poco::Util::XMLConfiguration(config_xml)); | 
|---|
| 41 | // do not throw exception if not found | 
|---|
| 42 | if (try_get) | 
|---|
| 43 | return configuration->getString(key, ""); | 
|---|
| 44 | return configuration->getString(key); | 
|---|
| 45 | } | 
|---|
| 46 |  | 
|---|
| 47 | #pragma GCC diagnostic ignored "-Wunused-function" | 
|---|
| 48 | #pragma GCC diagnostic ignored "-Wmissing-declarations" | 
|---|
| 49 |  | 
|---|
| 50 | int mainEntryClickHouseExtractFromConfig(int argc, char ** argv) | 
|---|
| 51 | { | 
|---|
| 52 | bool print_stacktrace = false; | 
|---|
| 53 | bool process_zk_includes = false; | 
|---|
| 54 | bool try_get = false; | 
|---|
| 55 | std::string log_level; | 
|---|
| 56 | std::string config_path; | 
|---|
| 57 | std::string key; | 
|---|
| 58 |  | 
|---|
| 59 | namespace po = boost::program_options; | 
|---|
| 60 |  | 
|---|
| 61 | po::options_description options_desc( "Allowed options"); | 
|---|
| 62 | options_desc.add_options() | 
|---|
| 63 | ( "help", "produce this help message") | 
|---|
| 64 | ( "stacktrace", po::bool_switch(&print_stacktrace), "print stack traces of exceptions") | 
|---|
| 65 | ( "process-zk-includes", po::bool_switch(&process_zk_includes), | 
|---|
| 66 | "if there are from_zk elements in config, connect to ZooKeeper and process them") | 
|---|
| 67 | ( "try", po::bool_switch(&try_get), "Do not warn about missing keys") | 
|---|
| 68 | ( "log-level", po::value<std::string>(&log_level)->default_value( "error"), "log level") | 
|---|
| 69 | ( "config-file,c", po::value<std::string>(&config_path)->required(), "path to config file") | 
|---|
| 70 | ( "key,k", po::value<std::string>(&key)->required(), "key to get value for"); | 
|---|
| 71 |  | 
|---|
| 72 | po::positional_options_description positional_desc; | 
|---|
| 73 | positional_desc.add( "config-file", 1); | 
|---|
| 74 | positional_desc.add( "key", 1); | 
|---|
| 75 |  | 
|---|
| 76 | try | 
|---|
| 77 | { | 
|---|
| 78 | po::variables_map options; | 
|---|
| 79 | po::store(po::command_line_parser(argc, argv).options(options_desc).positional(positional_desc).run(), options); | 
|---|
| 80 |  | 
|---|
| 81 | if (options.count( "help")) | 
|---|
| 82 | { | 
|---|
| 83 | std::cerr << "Preprocess config file and extract value of the given key."<< std::endl | 
|---|
| 84 | << std::endl; | 
|---|
| 85 | std::cerr << "Usage: clickhouse extract-from-config [options]"<< std::endl | 
|---|
| 86 | << std::endl; | 
|---|
| 87 | std::cerr << options_desc << std::endl; | 
|---|
| 88 | return 0; | 
|---|
| 89 | } | 
|---|
| 90 |  | 
|---|
| 91 | po::notify(options); | 
|---|
| 92 |  | 
|---|
| 93 | setupLogging(log_level); | 
|---|
| 94 | std::cout << extractFromConfig(config_path, key, process_zk_includes, try_get) << std::endl; | 
|---|
| 95 | } | 
|---|
| 96 | catch (...) | 
|---|
| 97 | { | 
|---|
| 98 | std::cerr << DB::getCurrentExceptionMessage(print_stacktrace, true) << std::endl; | 
|---|
| 99 | return DB::getCurrentExceptionCode(); | 
|---|
| 100 | } | 
|---|
| 101 |  | 
|---|
| 102 | return 0; | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|