blob: 9a7f26c3a1126c06f39119d037f41d4766f26ce0 [file] [log] [blame]
/**
*
* 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