MetroCollect  2.3.4
SourceProcMeminfo.cc
Go to the documentation of this file.
1 //
2 // SourceProcMeminfo.cc
3 //
4 // Created on August 23rd 2018
5 //
6 // Copyright 2018 CFM (www.cfm.fr)
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
19 //
20 
21 #include <algorithm>
22 #include <cstring>
23 
24 #include "SourceProcMeminfo.h"
25 
26 
30  this->parseFields();
31  }
32 
33 
35  bool read = readFile(this->file_, this->buffer_, SourceProcMeminfo::filePath);
36  if (!read)
37  return;
38 
39  const char* buffer = this->buffer_.data();
40 
41  this->fieldNames_.clear();
42  while (buffer[0] != '\0') {
43  size_t length = 0;
44  while (buffer[length] != ':')
45  length++;
46  this->fieldNames_.emplace_back(buffer, length);
47  buffer += length;
48  while (buffer[0] != '\n')
49  buffer++;
50  buffer++;
51  }
52 
53  for (auto& fieldName : this->fieldNames_) {
54  bool wasCapitalized = false;
55  for (size_t i = 0; i < fieldName.size(); i++) {
56  if (!isalnum(fieldName[i]) && fieldName[i] != '_')
57  fieldName[i] = '_';
58  else if (isupper(fieldName[i])) {
59  if (i > 0 && fieldName[i - 1] != '_' && islower(fieldName[i - 1]) && !wasCapitalized) {
60  fieldName.insert(i, "_");
61  i++;
62  }
63  fieldName[i] = tolower(fieldName[i]);
64  wasCapitalized = true;
65  } else
66  wasCapitalized = false;
67  }
68  while (fieldName.back() == '_')
69  fieldName.erase(fieldName.size() - 1);
70  while (fieldName.front() == '_')
71  fieldName.erase(0);
72  }
73  }
74 
75 
76  size_t SourceProcMeminfo::fieldCount() const noexcept {
77  return this->fieldNames_.size();
78  }
79 
80  const std::vector<size_t> SourceProcMeminfo::indexesOfFieldName(const FieldName& fieldName, Interests* interests) const noexcept {
81  if (fieldName.front() != SourceProcMeminfo::sourcePrefix)
82  return {};
83 
84  auto itr = std::find(this->fieldNames_.begin(), this->fieldNames_.end(), fieldName[1]);
85  if (itr != this->fieldNames_.end()) {
86  if (interests)
87  interests->set(0);
88  return {static_cast<size_t>(std::distance(this->fieldNames_.begin(), itr))};
89  }
90  return {};
91  }
92 
93  const std::string SourceProcMeminfo::fieldNameSourcePrefix() const noexcept {
94  return std::string(SourceProcMeminfo::sourcePrefix);
95  }
96 
97  const FieldInfo SourceProcMeminfo::fieldInfoAtIndex(size_t index) const noexcept {
98  FieldName name = {std::string(SourceProcMeminfo::sourcePrefix), this->fieldNames_[index]};
99  std::string unit = findUnit(this->fieldNames_[index], SourceProcMeminfo::fieldUnitsAssociation, SourceProcMeminfo::defaultUnit);
100  return {name, "Memory metric: " + this->fieldNames_[index], unit};
101  }
102 
103  const std::vector<FieldInfo> SourceProcMeminfo::allFieldsInfo() const noexcept {
104  std::vector<FieldInfo> info;
105  for (size_t i = 0; i < this->fieldNames_.size(); i++)
106  info.push_back(this->fieldInfoAtIndex(i));
107  return info;
108  }
109 
110 
112  bool read = false;
113  if (interests.none() || !(read = readFile(this->file_, this->buffer_, SourceProcMeminfo::filePath))) {
114  std::fill_n(current, this->fieldCount(), 0);
115  return;
116  }
117 
118  const char* buffer = this->buffer_.data();
119  while (buffer[0] != '\0') {
120  while (buffer[0] != ':')
121  buffer++;
122  buffer++;
123  *current = static_cast<DataValueType>(parseUint(buffer));
124  while (buffer[0] == ' ')
125  buffer++;
126  switch (buffer[0]) {
127  case 'T':
128  case 't':
129  *current *= 1024;
130  [[fallthrough]];
131  case 'G':
132  case 'g':
133  *current *= 1024;
134  [[fallthrough]];
135  case 'M':
136  case 'm':
137  *current *= 1024;
138  [[fallthrough]];
139  case 'K':
140  case 'k':
141  *current *= 1024;
142  buffer += 2;
143  break;
144  default:
145  break;
146  }
147  current++;
148  while (buffer[0] != '\n')
149  buffer++;
150  buffer++;
151  }
152  }
153 
154 
156  if (interests.none())
157  return;
158 
159  std::copy_n(current, this->fieldNames_.size(), diff);
160  }
161 }
Object used to describe a field (or metric)
Definition: SourceField.h:37
std::vector< std::string > FieldName
Type used for field names (an array of strings)
Definition: SourceField.h:31
bool readFile(std::ifstream &file, std::vector< char > &buffer, const std::string_view &path)
Attempts to read file into buffer.
Definition: SourceTools.cc:55
Namespace for sources of metrics objects and operations.
static constexpr std::string_view filePath
Memory metrics file path.
std::vector< DataValueType >::const_iterator ConstIterator
Const iterator type of MetricsDataArray.
Definition: MetricTypes.h:37
static constexpr std::string_view defaultUnit
Metric unit.
uint64_t parseUint(const char *&buffer) noexcept
Fast and unsafe unsigned integer parser.
Definition: SourceTools.h:40
static constexpr std::string_view sourcePrefix
Metrics name source prefix.
const FieldInfo fieldInfoAtIndex(size_t index) const noexcept override final
Get details about a specific field.
std::vector< std::string > fieldNames_
Metrics names.
const std::string fieldNameSourcePrefix() const noexcept override final
Get the prefix by which all field names should begin with.
const std::vector< size_t > indexesOfFieldName(const FieldName &fieldName, Interests *interests=nullptr) const noexcept override final
Search for fields associated to a specific name.
std::vector< char > buffer_
Buffer to put file contents into.
static constexpr std::array fieldUnitsAssociation
Metric units associations.
size_t fieldCount() const noexcept override final
Get the number of field the source has.
int64_t DataValueType
Type of fetched raw metrics.
Definition: MetricTypes.h:28
bool none() const
Checks wether all bit are false.
void computeDiff(const Interests &interests, DiffArray::Iterator diff, DataArray::ConstIterator current, DataArray::ConstIterator previous, double factor=1) noexcept override final
Compute the variation (in appropriate unit) of metrics.
Boolean array to keep track of which fields a source has to fetch metrics for.
std::vector< DiffValueType >::iterator Iterator
Iterator type of MetricsDiffArray.
Definition: MetricTypes.h:44
const std::vector< FieldInfo > allFieldsInfo() const noexcept override final
Get all fields details, field which share a common name should appear only once.
void fetchData(const Interests &interests, DataArray::Iterator current) override final
Fetch the latest metrics.
bool resetFile(std::ifstream &file, std::vector< char > &buffer, const std::string_view &path)
Attempts to open a file and set buffer size accordingly.
Definition: SourceTools.cc:25
SourceProcMeminfo()
Private default constructor.
std::string findUnit(const std::string &name, const std::array< KeyUnit, N > &keyUnitAssociation, const std::string_view &defaultUnit)
Tries to associate a field name with a unit, falling back on the default unit if none matches...
Definition: SourceTools.h:96
std::vector< DataValueType >::iterator Iterator
Iterator type of MetricsDataArray.
Definition: MetricTypes.h:36