16 :space_provider(
std::move(space_provider)),
22 sleep_time_in_secs = sleep_time;
28 SYS_ASSERT(new_warning_threshold < new_threshold, chain::plugin_config_exception,
29 "warning_threshold ${new_warning_threshold} must be less than threshold ${new_threshold}", (
"new_warning_threshold", new_warning_threshold) (
"new_threshold", new_threshold));
31 shutdown_threshold = new_threshold;
32 warning_threshold = new_warning_threshold;
36 shutdown_on_exceeded = new_shutdown_on_exceeded;
40 warning_interval = new_warning_interval;
45 for (
auto& fs: filesystems) {
46 boost::system::error_code ec;
47 auto info = space_provider.get_space(fs.path_name, ec);
52 wlog(
"Unable to get space info for ${path_name}: [code: ${ec}] ${message}. Ignore this failure.",
53 (
"path_name", fs.path_name.string())
55 (
"message", ec.message()));
60 if ( info.available < fs.shutdown_available ) {
61 if (output_threshold_warning) {
62 elog(
"Space usage warning: ${path}'s file system exceeded threshold ${threshold}%, available: ${available}, Capacity: ${capacity}, shutdown_available: ${shutdown_available}",
63 (
"path", fs.path_name.string())(
"threshold", shutdown_threshold)(
"available", info.available)(
"capacity", info.capacity)(
"shutdown_available", fs.shutdown_available));
66 }
else if ( info.available < fs.warning_available && output_threshold_warning ) {
67 wlog(
"Space usage warning: ${path}'s file system approaching threshold. available: ${available}, warning_available: ${warning_available}", (
"path", fs.path_name.string()) (
"available", info.available) (
"warning_available", fs.warning_available));
68 if ( shutdown_on_exceeded) {
69 wlog(
"nodeop will shutdown when space usage exceeds threshold ${threshold}%", (
"threshold", shutdown_threshold));
80 auto status = space_provider.get_stat(path_name.string().c_str(), &statbuf);
81 SYS_ASSERT(status == 0, chain::plugin_config_exception,
82 "Failed to run stat on ${path} with status ${status}", (
"path", path_name.string())(
"status", status));
84 dlog(
"${path_name}'s file system to be monitored", (
"path_name", path_name.string()));
88 for (
auto& fs: filesystems) {
89 if (statbuf.st_dev == fs.st_dev) {
90 dlog(
"${path_name}'s file system already monitored", (
"path_name", path_name.string()));
99 boost::system::error_code ec;
100 auto info = space_provider.get_space(path_name, ec);
101 SYS_ASSERT(!ec, chain::plugin_config_exception,
102 "Unable to get space info for ${path_name}: [code: ${ec}] ${message}",
103 (
"path_name", path_name.string())
105 (
"message", ec.message()));
107 auto shutdown_available = (100 - shutdown_threshold) * (info.capacity / 100);
108 auto warning_available = (100 - warning_threshold) * (info.capacity / 100);
111 filesystems.emplace_back(statbuf.st_dev, shutdown_available, path_name, warning_available);
113 ilog(
"${path_name}'s file system monitored. shutdown_available: ${shutdown_available}, capacity: ${capacity}, threshold: ${threshold}", (
"path_name", path_name.string()) (
"shutdown_available", shutdown_available) (
"capacity", info.capacity) (
"threshold", shutdown_threshold) );
118 elog(
"Shutting down, file system exceeded threshold");
122 update_warning_interval_counter();
124 timer.expires_from_now( boost::posix_time::seconds( sleep_time_in_secs ));
126 timer.async_wait([
this](
auto& ec) {
128 wlog(
"Exit due to error: ${ec}, message: ${message}",
130 (
"message", ec.message()));
140 SpaceProvider space_provider;
142 boost::asio::deadline_timer timer;
147 bool shutdown_on_exceeded {
true};
149 struct filesystem_info {
155 filesystem_info(dev_t dev,
uintmax_t available,
const bfs::path& path,
uintmax_t warning)
157 shutdown_available(available),
159 warning_available(warning)
166 std::vector<filesystem_info> filesystems;
169 uint32_t warning_interval_counter {1};
170 bool output_threshold_warning {
true};
172 void update_warning_interval_counter() {
173 if ( warning_interval_counter == warning_interval ) {
174 output_threshold_warning =
true;
175 warning_interval_counter = 1;
177 output_threshold_warning =
false;
178 ++warning_interval_counter;