extensions/procfs/ProcFs.cpp (87 lines of code) (raw):
/**
* 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 "ProcFs.h"
#include <istream>
namespace org::apache::nifi::minifi::extensions::procfs {
namespace {
bool is_number(const std::string& s) {
return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
}
} // namespace
std::map<pid_t, ProcessStat> ProcFs::getProcessStats() const {
std::map<pid_t, ProcessStat> process_stats;
for (const auto& entry : std::filesystem::directory_iterator(root_path_)) {
if (entry.is_directory() && is_number(entry.path().filename())) {
auto stat_file_path = entry.path() / STAT_FILE;
std::ifstream stat_file(stat_file_path);
if (auto process_stat_data = ProcessStatData::parseProcessStatFile(stat_file)) {
process_stats.emplace(process_stat_data->getPid(), ProcessStat(*process_stat_data, page_size_));
} else {
logger_->log_error("Failed to parse %s", entry.path());
}
}
}
return process_stats;
}
std::vector<std::pair<std::string, CpuStatData>> ProcFs::getCpuStats() const {
std::vector<std::pair<std::string, CpuStatData>> cpu_stats;
auto stat_file_path = root_path_ / STAT_FILE;
std::ifstream stat_file;
stat_file.open(stat_file_path);
std::string line;
while (std::getline(stat_file, line)) {
std::istringstream iss(line);
std::string entry_name;
iss >> entry_name;
if (entry_name.starts_with("cpu")) {
if (auto cpu_stat_data = CpuStatData::parseCpuStatLine(iss)) {
cpu_stats.emplace_back(entry_name, *cpu_stat_data);
} else {
logger_->log_error("Failed to parse %s from %s", entry_name, stat_file_path);
}
}
}
return cpu_stats;
}
std::vector<std::pair<std::string, NetDevData>> ProcFs::getNetDevs() const {
std::vector<std::pair<std::string, NetDevData>> net_devs;
auto stat_file_path = root_path_ / NET_DEV_FILE;
std::ifstream stat_file;
stat_file.open(stat_file_path);
std::string line;
std::getline(stat_file, line); // The first two lines are headers
std::getline(stat_file, line);
int line_num = 0;
while (std::getline(stat_file, line)) {
++line_num;
std::istringstream iss(line);
if (auto net_dev = NetDevData::parseNetDevLine(iss)) {
net_devs.emplace_back(net_dev->first, net_dev->second);
} else {
logger_->log_error("Failed to parse line %d from %s", line_num, stat_file_path);
}
}
return net_devs;
}
std::vector<std::pair<std::string, DiskStatData>> ProcFs::getDiskStats() const {
std::vector<std::pair<std::string, DiskStatData>> disk_stats;
auto disk_stats_file_path = root_path_ / DISK_STATS_FILE;
std::ifstream stat_file;
stat_file.open(disk_stats_file_path);
std::string line;
int line_num = 0;
while (std::getline(stat_file, line)) {
++line_num;
std::istringstream iss(line);
if (auto disk_stat = DiskStatData::parseDiskStatLine(iss)) {
disk_stats.emplace_back(disk_stat->first, disk_stat->second);
} else {
logger_->log_error("Failed to parse line %d from %s", line_num, disk_stats_file_path);
}
}
return disk_stats;
}
std::optional<MemInfo> ProcFs::getMemInfo() const {
auto mem_info_file_path = root_path_ / MEMINFO_FILE;
std::ifstream mem_info_file(mem_info_file_path);
return MemInfo::parseMemInfoFile(mem_info_file);
}
} // namespace org::apache::nifi::minifi::extensions::procfs