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 | |