MetroCollect  2.3.4
SourceProcNetDev.cc
Go to the documentation of this file.
1 //
2 // SourceProcNetDev.cc
3 //
4 // Created on August 27th 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 "SourceProcNetDev.h"
25 
26 
30  this->parseFields();
31  }
32 
33 
35  bool read = readFile(this->file_, this->buffer_, SourceProcNetDev::filePath);
36  if (!read)
37  return;
38 
39  const char* buffer = std::strchr(this->buffer_.data(), '\n') + 1;
40  buffer = std::strchr(buffer, '|') + 1;
41 
42  this->rxFieldNames_.clear();
43  while(buffer[0] != '|') {
44  while (!std::isalnum(buffer[0]))
45  buffer++;
46  size_t length = 0;
47  while (std::isalnum(buffer[length]))
48  length++;
49  this->rxFieldNames_.emplace_back(buffer, length);
50  buffer += length;
51  }
52  buffer++;
53 
54  this->txFieldNames_.clear();
55  while(buffer[0] != '\n') {
56  while (!std::isalnum(buffer[0]))
57  buffer++;
58  size_t length = 0;
59  while (std::isalnum(buffer[length]))
60  length++;
61  this->txFieldNames_.emplace_back(buffer, length);
62  buffer += length;
63  }
64  buffer++;
65 
66  this->interfaces_.clear();
67  while (buffer[0] != '\0') {
68  while (!std::isalnum(buffer[0]))
69  buffer++;
70  size_t length = 0;
71  while (std::isalnum(buffer[length]))
72  length++;
73  this->interfaces_.emplace_back(buffer, length);
74  buffer += length;
75  while (buffer[0] != '\n')
76  buffer++;
77  buffer++;
78  }
79  }
80 
81 
82  size_t SourceProcNetDev::fieldCount() const noexcept {
83  return this->interfaces_.size() * (this->rxFieldNames_.size() + this->txFieldNames_.size());
84  }
85 
86  const std::vector<size_t> SourceProcNetDev::indexesOfFieldName(const FieldName& fieldName, Interests* interests) const noexcept {
87  if (fieldName.front() != SourceProcNetDev::sourcePrefix)
88  return {};
89 
90  size_t baseIndex = -1;
91  if (fieldName[2] == SourceProcNetDev::fieldRecieve) {
92  auto itr = std::find(this->rxFieldNames_.begin(), this->rxFieldNames_.end(), fieldName[3]);
93  if (itr != this->rxFieldNames_.end()) {
94  if (interests)
95  interests->set(0);
96  baseIndex = std::distance(this->rxFieldNames_.begin(), itr);
97  }
98  }
99  else if (fieldName[2] == SourceProcNetDev::fieldTransmit) {
100  auto itr = std::find(this->txFieldNames_.begin(), this->txFieldNames_.end(), fieldName[3]);
101  if (itr != this->txFieldNames_.end()) {
102  if (interests)
103  interests->set(0);
104  baseIndex = this->rxFieldNames_.size() + std::distance(this->txFieldNames_.begin(), itr);
105  }
106  } else
107  return {};
108 
109  if (baseIndex < this->rxFieldNames_.size() + this->txFieldNames_.size()) {
110  if (fieldName[1] == fieldNameAll) {
111  std::vector<size_t> indexes;
112  indexes.resize(this->interfaces_.size(), 0);
113  for (size_t i = 0; i < indexes.size(); i++)
114  indexes[i] = i * (this->rxFieldNames_.size() + this->txFieldNames_.size()) + baseIndex;
115  return indexes;
116  }
117  auto itr = std::find(this->interfaces_.begin(), this->interfaces_.end(), fieldName[1]);
118  if (itr != this->interfaces_.end())
119  return {std::distance(this->interfaces_.begin(), itr) * (this->rxFieldNames_.size() + this->txFieldNames_.size()) + baseIndex};
120  }
121 
122  return {};
123  }
124 
125  const std::string SourceProcNetDev::fieldNameSourcePrefix() const noexcept {
126  return std::string(SourceProcNetDev::sourcePrefix);
127  }
128 
129  const FieldInfo SourceProcNetDev::fieldInfoAtIndex(size_t index) const noexcept {
130  size_t ifIndex = index / (this->rxFieldNames_.size() + this->txFieldNames_.size());
131  size_t fieldIndex = index % (this->rxFieldNames_.size() + this->txFieldNames_.size());
132  bool isRx = fieldIndex < this->rxFieldNames_.size();
133  if (!isRx)
134  fieldIndex -= this->rxFieldNames_.size();
135  std::string fieldKind = (isRx ? std::string(SourceProcNetDev::fieldRecieve) : std::string(SourceProcNetDev::fieldTransmit));
136  std::string fieldName = (isRx ? this->rxFieldNames_[fieldIndex] : this->txFieldNames_[fieldIndex]);
137  FieldName name = {std::string(SourceProcNetDev::sourcePrefix), this->interfaces_[ifIndex], fieldKind, fieldName};
139  return {name, "Network interface " + this->interfaces_[ifIndex] + " metric: " + fieldKind + "/" + fieldName, unit, 1, std::string(SourceProcNetDev::fieldNameInterfaceDescription)};
140  }
141 
142  const std::vector<FieldInfo> SourceProcNetDev::allFieldsInfo() const noexcept {
143  std::vector<FieldInfo> info;
144  for (size_t i = 0; i < this->rxFieldNames_.size() + this->txFieldNames_.size(); i++) {
145  info.push_back(this->fieldInfoAtIndex(i));
146  info.back().name[info.back().dynamicIndexes[0].index] = SourceProcNetDev::fieldNameAll;
147  }
148  return info;
149  }
150 
151 
153  bool read = false;
154  if (interests.none() || !(read = readFile(this->file_, this->buffer_, SourceProcNetDev::filePath))) {
155  std::fill_n(current, this->fieldCount(), 0);
156  return;
157  }
158 
159  size_t remainingInterfaces = this->interfaces_.size();
160  const char* buffer = this->buffer_.data();
161  while (buffer[0] != '\n')
162  buffer++;
163  buffer++;
164  while (buffer[0] != '\n')
165  buffer++;
166  buffer++;
167 
168  while (remainingInterfaces > 0 && buffer[0] != '\0') {
169  while (buffer[0] != ':')
170  buffer++;
171  buffer++;
172  while (buffer[0] != '\n') {
173  buffer++;
174  *current = static_cast<DataValueType>(parseUint(buffer));
175  current++;
176  }
177  buffer++;
178  remainingInterfaces--;
179  }
180  }
181 
182 
183  void SourceProcNetDev::computeDiff(const Interests& interests, DiffArray::Iterator diff, DataArray::ConstIterator current, DataArray::ConstIterator previous, double factor) noexcept {
184  if (interests.none())
185  return;
186 
187  for (size_t i = 0; i < this->fieldCount(); i++) {
188  *diff = static_cast<DiffValueType>((*current - *previous) * factor);
189  diff++;
190  current++;
191  previous++;
192  }
193  }
194 }
Object used to describe a field (or metric)
Definition: SourceField.h:37
std::vector< std::string > rxFieldNames_
Reception metric names.
static constexpr std::array fieldUnitsAssociation
Metric units associations.
std::vector< std::string > txFieldNames_
Transmission metric names.
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< 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.
std::vector< DataValueType >::const_iterator ConstIterator
Const iterator type of MetricsDataArray.
Definition: MetricTypes.h:37
uint64_t parseUint(const char *&buffer) noexcept
Fast and unsafe unsigned integer parser.
Definition: SourceTools.h:40
void fetchData(const Interests &interests, DataArray::Iterator current) override final
Fetch the latest metrics.
std::vector< char > buffer_
Buffer to put file contents into.
SourceProcNetDev()
Private default constructor.
const std::vector< FieldInfo > allFieldsInfo() const noexcept override final
Get all fields details, field which share a common name should appear only once.
static constexpr std::string_view fieldNameAll
Metrics name wildcard.
static constexpr std::string_view sourcePrefix
Metrics name source prefix.
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.
static constexpr std::string_view filePath
Network metrics file path.
int64_t DataValueType
Type of fetched raw metrics.
Definition: MetricTypes.h:28
bool none() const
Checks wether all bit are false.
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
size_t fieldCount() const noexcept override final
Get the number of field the source has.
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
static constexpr std::string_view fieldRecieve
Metrics name category.
static constexpr std::string_view defaultUnit
Metric unit.
static constexpr std::string_view fieldTransmit
Metrics name category.
static constexpr std::string_view fieldNameInterfaceDescription
Metrics name category description.
const std::string fieldNameSourcePrefix() const noexcept override final
Get the prefix by which all field names should begin with.
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
std::vector< std::string > interfaces_
Network interfaces names.
const FieldInfo fieldInfoAtIndex(size_t index) const noexcept override final
Get details about a specific field.
double DiffValueType
Type of metric variation.
Definition: MetricTypes.h:29