2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright (C) 2014 Cloudius Systems, Ltd.
22 #include <seastar/core/app-template.hh>
23 #include <seastar/core/reactor.hh>
24 #include <seastar/core/scollectd.hh>
25 #include <seastar/core/metrics_api.hh>
26 #include <boost/program_options.hpp>
27 #include <seastar/core/print.hh>
28 #include <seastar/util/log.hh>
29 #include <seastar/util/log-cli.hh>
30 #include <boost/program_options.hpp>
31 #include <boost/make_shared.hpp>
37 namespace bpo
= boost::program_options
;
39 app_template::app_template(app_template::config cfg
)
40 : _cfg(std::move(cfg
))
41 , _opts(_cfg
.name
+ " options")
42 , _conf_reader(get_default_configuration_reader()) {
44 ("help,h", "show help message")
47 _opts_conf_file
.add(reactor::get_options_description(cfg
.default_task_quota
));
48 _opts_conf_file
.add(seastar::metrics::get_options_description());
49 _opts_conf_file
.add(smp::get_options_description());
50 _opts_conf_file
.add(scollectd::get_options_description());
51 _opts_conf_file
.add(log_cli::get_options_description());
53 _opts
.add(_opts_conf_file
);
56 app_template::configuration_reader
app_template::get_default_configuration_reader() {
57 return [this] (bpo::variables_map
& configuration
) {
58 auto home
= std::getenv("HOME");
60 std::ifstream
ifs(std::string(home
) + "/.config/seastar/seastar.conf");
62 bpo::store(bpo::parse_config_file(ifs
, _opts_conf_file
), configuration
);
64 std::ifstream
ifs_io(std::string(home
) + "/.config/seastar/io.conf");
66 bpo::store(bpo::parse_config_file(ifs_io
, _opts_conf_file
), configuration
);
72 void app_template::set_configuration_reader(configuration_reader conf_reader
) {
73 _conf_reader
= conf_reader
;
76 boost::program_options::options_description
& app_template::get_options_description() {
80 boost::program_options::options_description
& app_template::get_conf_file_options_description() {
81 return _opts_conf_file
;
84 boost::program_options::options_description_easy_init
85 app_template::add_options() {
86 return _opts
.add_options();
90 app_template::add_positional_options(std::initializer_list
<positional_option
> options
) {
91 for (auto&& o
: options
) {
92 _opts
.add(boost::make_shared
<bpo::option_description
>(o
.name
, o
.value_semantic
, o
.help
));
93 _pos_opts
.add(o
.name
, o
.max_count
);
99 app_template::configuration() {
100 return *_configuration
;
104 app_template::run(int ac
, char ** av
, std::function
<future
<int> ()>&& func
) {
105 return run_deprecated(ac
, av
, [func
= std::move(func
)] () mutable {
106 auto func_done
= make_lw_shared
<promise
<>>();
107 engine().at_exit([func_done
] { return func_done
->get_future(); });
108 futurize_apply(func
).finally([func_done
] {
109 func_done
->set_value();
110 }).then([] (int exit_code
) {
111 return engine().exit(exit_code
);
117 app_template::run(int ac
, char ** av
, std::function
<future
<> ()>&& func
) {
118 return run(ac
, av
, [func
= std::move(func
)] {
119 return func().then([] () {
126 app_template::run_deprecated(int ac
, char ** av
, std::function
<void ()>&& func
) {
128 fmt::print("WARNING: debug mode. Not for benchmarking or production\n");
130 bpo::variables_map configuration
;
132 bpo::store(bpo::command_line_parser(ac
, av
)
134 .positional(_pos_opts
)
137 _conf_reader(configuration
);
138 } catch (bpo::error
& e
) {
139 fmt::print("error: {}\n\nTry --help.\n", e
.what());
142 if (configuration
.count("help")) {
143 std::cout
<< _opts
<< "\n";
146 if (configuration
["help-loggers"].as
<bool>()) {
147 log_cli::print_available_loggers(std::cout
);
151 bpo::notify(configuration
);
153 // Needs to be before `smp::configure()`.
155 apply_logging_settings(log_cli::extract_settings(configuration
));
156 } catch (const std::runtime_error
& exn
) {
157 std::cout
<< "logging configuration error: " << exn
.what() << '\n';
161 configuration
.emplace("argv0", boost::program_options::variable_value(std::string(av
[0]), false));
163 smp::configure(configuration
);
165 std::cerr
<< "Could not initialize seastar: " << std::current_exception() << std::endl
;
168 _configuration
= {std::move(configuration
)};
169 engine().when_started().then([this] {
170 seastar::metrics::configure(this->configuration()).then([this] {
171 // set scollectd use the metrics configuration, so the later
172 // need to be set first
173 scollectd::configure( this->configuration());
177 ).then_wrapped([] (auto&& f
) {
180 } catch (std::exception
& ex
) {
181 std::cout
<< "program failed with uncaught exception: " << ex
.what() << "\n";
185 auto exit_code
= engine().run();