AnyCollect  1.1.2
SnapInterface.cc
Go to the documentation of this file.
1 //
2 // SnapInterface.cc
3 //
4 // Created on October 25th 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 
23 #include "SnapInterface.h"
24 
25 
26 namespace AnyCollect {
27  std::hash<std::string> SnapInterface::hasher{};
28 
30  controller_(*this),
31  sendAllMetrics_(false)
32  { }
33 
34 
35  void SnapInterface::insertAppPrefixToNamespace(std::vector<std::string>& ns) {
36  std::transform(SnapInterface::appPrefix.begin(), SnapInterface::appPrefix.end(), std::inserter(ns, ns.begin()), [&](auto s) {
37  return std::string(s);
38  });
39  }
40 
41  void SnapInterface::setConfig(const Plugin::Config& cfg) {
42  std::chrono::seconds sampling = Controller::defaultSamplingInterval;
43  std::string configPath;
45 
46  if (cfg.has_int_key(std::string(SnapInterface::configKeySamplingInterval)))
47  sampling = std::chrono::seconds(cfg.get_int(std::string(SnapInterface::configKeySamplingInterval)));
48  if (cfg.has_string_key(std::string(SnapInterface::configKeyConfigFile)))
49  configPath = cfg.get_string(std::string(SnapInterface::configKeyConfigFile));
50  if (cfg.has_bool_key(std::string(SnapInterface::configKeySendAllMetrics)))
51  sendAll = cfg.get_bool(std::string(SnapInterface::configKeySendAllMetrics));
52 
53  this->controller_.setSamplingInterval(sampling);
54  this->controller_.loadConfigFromFile(configPath);
55  this->sendAllMetrics_ = sendAll;
56  }
57 
58  void SnapInterface::formatName(std::vector<std::string>& name) {
59  for (auto& part : name) {
60  bool wasCapitalized = false;
61  for (size_t i = 0; i < part.size(); i++) {
62  if (!std::isalnum(part[i]) && part[i] != '_') {
63  if (i > 0 && part[i - 1] != '_') {
64  part[i] = '_';
65  } else {
66  part.erase(i, 1);
67  i--;
68  }
69  }
70  else if (std::isupper(part[i])) {
71  if (i > 0 && part[i - 1] != '_' && std::islower(part[i - 1]) && !wasCapitalized) {
72  part.insert(i, "_");
73  i++;
74  }
75  part[i] = std::tolower(part[i]);
76  wasCapitalized = true;
77  } else
78  wasCapitalized = false;
79  }
80  while (part.back() == '_')
81  part.erase(part.size() - 1, 1);
82  while (part.front() == '_')
83  part.erase(0, 1);
84  }
85  }
86 
88  std::string nameHash;
89  std::vector<std::string> name = m.name();
90  this->formatName(name);
91  for (const auto& n : name)
92  nameHash.append(n);
93  return SnapInterface::hasher(nameHash);
94  }
95 
96  size_t SnapInterface::computeNameKey(const Plugin::Metric& m) {
97  std::string nameHash;
98  for (size_t i = 2; i < m.ns().size(); i++)
99  nameHash.append(m.ns()[i].get_value());
100  return SnapInterface::hasher(nameHash);
101  }
102 
103  Plugin::Metric SnapInterface::convertToSnapMetric(const Metric& metric) {
104  std::vector<std::string> name = metric.name();
105  this->formatName(name);
106  this->insertAppPrefixToNamespace(name);
107  Plugin::Namespace ns{name};
108  Plugin::Metric snapMetric{ns, metric.unit(), ""};
109  for (const auto& tag : metric.tags())
110  snapMetric.add_tag(tag);
111  snapMetric.set_data(metric.value());
112  snapMetric.set_timestamp(metric.timestamp());
113  return snapMetric;
114  }
115 
116 
117  const Plugin::ConfigPolicy SnapInterface::get_config_policy() {
118  Plugin::ConfigPolicy policy;
119  std::vector<std::string> ns;
120  std::vector<std::string> baseNamespace;
121  this->insertAppPrefixToNamespace(baseNamespace);
122 
123  ns = baseNamespace;
124  ns.emplace_back(SnapInterface::configKeyConfigFile);
125  policy.add_rule(ns, Plugin::StringRule{std::string(SnapInterface::configKeyConfigFile), {true}});
126 
127  for (size_t i = 0; i < SnapInterface::configKeysInt.size(); i++) {
128  ns = baseNamespace;
129  ns.emplace_back(SnapInterface::configKeysInt[i]);
130  policy.add_rule(ns, Plugin::IntRule{std::string(SnapInterface::configKeysInt[i]), {SnapInterface::configValuesInt[i], false}});
131  }
132  for (size_t i = 0; i < SnapInterface::configKeysBool.size(); i++) {
133  ns = baseNamespace;
134  ns.emplace_back(SnapInterface::configKeysBool[i]);
135  policy.add_rule(ns, Plugin::BoolRule{std::string(SnapInterface::configKeysBool[i]), {SnapInterface::configValuesBool[i], false}});
136  }
137  return policy;
138  }
139 
140  std::vector<Plugin::Metric> SnapInterface::get_metric_types(Plugin::Config cfg) {
141  std::vector<Plugin::Metric> metrics;
142  this->setConfig(cfg);
143 
144  auto availableMetrics = this->controller_.availableMetrics();
145  for (auto& m : availableMetrics)
146  metrics.push_back(this->convertToSnapMetric(*m));
147 
148  std::vector<std::string> name = {std::string(SnapInterface::configKeySendAllMetrics)};
149  this->insertAppPrefixToNamespace(name);
150  Plugin::Namespace ns{name};
151  metrics.emplace_back(ns, "", "");
152 
153  return metrics;
154  }
155 
156  void SnapInterface::get_metrics_in(std::vector<Plugin::Metric> &metsIn) {
157  if (metsIn.size() == 0)
158  return;
159 
160  this->setConfig(metsIn.front().get_config());
161 
162  this->requestedMetrics_.clear();
163  for (const auto& m : metsIn) {
164  if (m.ns().size() == (SnapInterface::appPrefix.size() + 1) && m.ns()[2].get_value() == SnapInterface::configKeySendAllMetrics)
165  this->sendAllMetrics_ = true;
166  else
167  this->requestedMetrics_.insert(this->computeNameKey(m));
168  }
169 
170  auto availableMetrics = this->controller_.availableMetrics();
171  this->metrics_.clear();
172  this->unwantedMetrics_.clear();
173  for (const auto& m : availableMetrics) {
174  if (this->sendAllMetrics_ || this->requestedMetrics_.count(this->computeNameKey(*m)) > 0)
175  this->metrics_.insert_or_assign(m->key(), this->convertToSnapMetric(*m));
176  else
177  this->unwantedMetrics_.insert(m->key());
178  }
179  }
180 
181 
183  if (!this->sendAllMetrics_ && this->requestedMetrics_.empty())
184  return;
185 
186  this->controller_.collectMetrics();
187  }
188 
189 
190  void SnapInterface::contollerCollectedMetrics(const AnyCollect::Controller& , const std::vector<const AnyCollect::Metric*>& metrics) {
191  this->metricsToSend_.clear();
192  for (const auto& metric : metrics) {
193  auto itr = this->metrics_.find(metric->key());
194  if (itr != this->metrics_.end()) {
195  itr->second.set_data(metric->value());
196  itr->second.set_timestamp(metric->timestamp());
197  this->metricsToSend_.push_back(&itr->second);
198  } else if (this->sendAllMetrics_) {
199  auto itr3 = this->metrics_.insert_or_assign(metric->key(), this->convertToSnapMetric(*metric));
200  this->metricsToSend_.push_back(&itr3.first->second);
201  } else {
202  auto itr2 = this->unwantedMetrics_.find(metric->key());
203  if (itr2 == this->unwantedMetrics_.end()) {
204  if (this->requestedMetrics_.count(this->computeNameKey(*metric)) > 0) {
205  auto itr3 = this->metrics_.insert_or_assign(metric->key(), this->convertToSnapMetric(*metric));
206  this->metricsToSend_.push_back(&itr3.first->second);
207  } else {
208  this->unwantedMetrics_.insert(metric->key());
209  }
210  }
211  }
212  }
213  this->send_metrics(this->metricsToSend_);
214  }
215 
217  return this->context_cancelled();
218  }
219 }
220 
221 
222 int main(int argc, char* argv[]) {
223  Plugin::Meta meta(Plugin::Type::StreamCollector, std::string(AnyCollect::SnapInterface::appName), AnyCollect::SnapInterface::appVersion, Plugin::RpcType::GRPCStream);
224  meta.concurrency_count = 1;
225  meta.exclusive = false;
226  meta.strategy = Plugin::Strategy::Sticky;
227  meta.cache_ttl = 1ms;
229  Plugin::start_stream_collector(argc, argv, &plugin, meta);
230  return 0;
231 }
std::vector< Plugin::Metric > get_metric_types(Plugin::Config cfg) override final
Returns all metrics that can be fetched by the plugin to Snap.
void loadConfigFromFile(const std::string &configPath)
Configures sources, expressions and matchers according to config file.
Definition: Controller.cc:54
int main(int argc, char *argv[])
AnyCollect&#39;s main function.
static constexpr bool defaultSendAllMetrics
Snap plugin configuration default value.
Definition: SnapInterface.h:50
const Plugin::ConfigPolicy get_config_policy() override final
Returns the plugin configuration keys and default values to Snap.
void setSamplingInterval(std::chrono::seconds interval) noexcept
Sets the metrics sampling interval.
Definition: Controller.cc:96
void contollerCollectedMetrics(const Controller &controller, const std::vector< const Metric *> &metrics) override final
Function called every time the Controller has collected metrics.
static constexpr std::chrono::seconds defaultSamplingInterval
Default parameter option.
Definition: Controller.h:48
static constexpr std::array< int, configKeysBool.size()> configValuesBool
Array of boolean-valued configuration default values.
Definition: SnapInterface.h:54
const std::string & unit() const noexcept
Returns the unit of the metric.
Definition: Metric.cc:115
std::set< size_t > unwantedMetrics_
Array of keys of non requested metrics.
Definition: SnapInterface.h:60
const std::vector< std::string > & name() const noexcept
Returns the name of the metric.
Definition: Metric.cc:95
std::map< size_t, Plugin::Metric > metrics_
Map associating keys to their metric.
Definition: SnapInterface.h:58
static constexpr std::array configKeysInt
Array of integer-valued configuration keys.
Definition: SnapInterface.h:48
static std::hash< std::string > hasher
Object used to compute keys (string hashes)
Definition: SnapInterface.h:55
void stream_metrics() override final
Stream metrics to Snap.
void insertAppPrefixToNamespace(std::vector< std::string > &ns)
Inserts plugin name prefix into Snap namespace.
SnapInterface()
Construct a new Snap Interface object.
void formatName(std::vector< std::string > &name)
Formats a metric name to be compatible with Snap requirements.
std::chrono::system_clock::time_point timestamp() const noexcept
Returns the timestamp of the metric.
Definition: Metric.cc:111
static constexpr std::string_view appName
Snap plugin name.
Definition: SnapInterface.h:39
AnyCollect::Controller controller_
Controller used to collect statistics.
Definition: SnapInterface.h:57
bool contollerShouldStopCollectingMetrics(const Controller &controller) override final
Function called after each iteration to ask the delegate whether the controller should stop collectin...
std::vector< Plugin::Metric * > metricsToSend_
Array of pointers to Snap metrics to be sent.
Definition: SnapInterface.h:62
void collectMetrics() noexcept
Launch metric collection loop.
Definition: Controller.cc:128
const std::map< std::string, std::string > & tags() const noexcept
Returns the tags of the metric.
Definition: Metric.cc:119
void get_metrics_in(std::vector< Plugin::Metric > &metsIn) override final
Gets the user&#39;s requested metrics from Snap.
static constexpr std::array< int, configKeysInt.size()> configValuesInt
Array of integer-valued configuration default values.
Definition: SnapInterface.h:53
static constexpr std::string_view configKeySamplingInterval
Snap plugin configuration key.
Definition: SnapInterface.h:44
size_t computeNameKey(const Metric &m)
Computes a key based solely on a metric&#39;s name.
Class used to represent a metric object (with a name, unit, tags, a value and a timestamp) ...
Definition: Metric.h:33
std::set< size_t > requestedMetrics_
Array of keys of requested metrics.
Definition: SnapInterface.h:59
Plugin::Metric convertToSnapMetric(const Metric &metric)
Converts a metric object into a Snap metric object.
void setConfig(const Plugin::Config &cfg)
Configures the plugin and the controller accordingly, unspecified values are reset to default...
std::vector< const Metric * > availableMetrics() noexcept
Returns the array of all currently matching metrics on the system, without their values.
Definition: Controller.cc:108
bool sendAllMetrics_
Whether to send all metrics, regardless of which are requested.
Definition: SnapInterface.h:61
static constexpr int appVersion
Snap plugin version.
Definition: SnapInterface.h:38
double value() const noexcept
Returns the value of the metric.
Definition: Metric.cc:107
static constexpr std::array appPrefix
Snap metric name prefix.
Definition: SnapInterface.h:42
static constexpr std::string_view configKeyConfigFile
Snap plugin configuration key.
Definition: SnapInterface.h:43
static constexpr std::string_view configKeySendAllMetrics
Snap plugin configuration key.
Definition: SnapInterface.h:45
static constexpr std::array configKeysBool
Array of boolean-valued configuration keys.
Definition: SnapInterface.h:49