| /** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "DiskSpaceWatchdog.h" |
| |
| #include "core/Property.h" |
| #include "core/logging/Logger.h" |
| #include "properties/Configure.h" |
| #include "utils/file/PathUtils.h" |
| |
| namespace org { |
| namespace apache { |
| namespace nifi { |
| namespace minifi { |
| |
| namespace { |
| namespace chr = std::chrono; |
| |
| utils::optional<chr::milliseconds> time_string_to_milliseconds(const std::string& str) { |
| uint64_t millisec_value{}; |
| const bool success = core::Property::getTimeMSFromString(str, millisec_value); |
| if (!success) return utils::nullopt; |
| return utils::make_optional(chr::milliseconds{millisec_value}); |
| } |
| |
| template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> |
| utils::optional<T> data_size_string_to_int(const std::string& str) { |
| T result{}; |
| // actually aware of data units like B, kB, MB, etc. |
| const bool success = core::Property::StringToInt(str, result); |
| if (!success) return utils::nullopt; |
| return utils::make_optional(result); |
| } |
| |
| |
| } // namespace |
| |
| namespace disk_space_watchdog { |
| Config read_config(const Configure& conf) { |
| const auto interval_ms = conf.get(Configure::minifi_disk_space_watchdog_interval) | utils::flatMap(time_string_to_milliseconds); |
| const auto stop_bytes = conf.get(Configure::minifi_disk_space_watchdog_stop_threshold) | utils::flatMap(data_size_string_to_int<std::uintmax_t>); |
| const auto restart_bytes = conf.get(Configure::minifi_disk_space_watchdog_restart_threshold) | utils::flatMap(data_size_string_to_int<std::uintmax_t>); |
| if (restart_bytes < stop_bytes) { throw std::runtime_error{"disk space watchdog stop threshold must be <= restart threshold"}; } |
| constexpr auto mebibytes = 1024 * 1024; |
| return { |
| interval_ms.value_or(chr::seconds{15}), |
| stop_bytes.value_or(100 * mebibytes), |
| restart_bytes.value_or(150 * mebibytes) |
| }; |
| } |
| |
| |
| std::vector<std::uintmax_t> check_available_space(const std::vector<std::string>& paths, core::logging::Logger* logger) { |
| std::vector<std::uintmax_t> result; |
| result.reserve(paths.size()); |
| std::transform(std::begin(paths), std::end(paths), std::back_inserter(result), [logger](const std::string& path) { |
| std::error_code ec; |
| const auto result = utils::file::space(path.c_str(), ec); |
| if (ec && logger) { |
| logger->log_info("Couldn't check disk space at %s: %s (ignoring)", path, ec.message()); |
| } else if (logger) { |
| logger->log_trace("%s available space: %zu bytes", path, gsl::narrow_cast<size_t>(result.available)); |
| } |
| return result.available; |
| }); |
| return result; |
| } |
| |
| } // namespace disk_space_watchdog |
| } // namespace minifi |
| } // namespace nifi |
| } // namespace apache |
| } // namespace org |