artdaq_utilities  v1_05_05
MetricManager.cc
1 // MetricManager.cc: MetricManager class implementation file
2 // Author: Eric Flumerfelt
3 // Last Modified: 11/14/2014
4 //
5 // MetricManager loads a user-specified set of plugins, sends them their configuration,
6 // and sends them data as it is recieved. It also maintains the state of the plugins
7 // relative to the application state.
8 
9 #define TRACE_NAME "MetricManager"
10 #include "artdaq-utilities/Plugins/MetricManager.hh"
11 #include "artdaq-utilities/Plugins/makeMetricPlugin.hh"
12 #include "fhiclcpp/ParameterSet.h"
13 #include "tracemf.h"
14 
15 #include <boost/exception/all.hpp>
16 #include <chrono>
17 
19  : metric_plugins_(0)
20  , metric_send_interval_ms_(15000)
21  , metric_holdoff_us_(1000)
22  , system_metric_collector_(nullptr)
23  , initialized_(false)
24  , running_(false)
25  , active_(false)
26  , busy_(false)
27  , missed_metric_calls_(0)
28  , metric_calls_(0)
29  , metric_cache_max_size_(1000)
30  , metric_cache_notify_size_(10) {}
31 
32 artdaq::MetricManager::~MetricManager() noexcept { shutdown(); }
33 
34 void artdaq::MetricManager::initialize(fhicl::ParameterSet const& pset, std::string const& prefix)
35 {
36  prefix_ = prefix;
37  if (initialized_)
38  {
39  shutdown();
40  }
41  TLOG(TLVL_INFO) << "Configuring metrics with parameter set: " << pset.to_string();
42 
43  std::vector<std::string> names = pset.get_names();
44 
45  metric_plugins_.clear();
46  bool send_system_metrics = false;
47  bool send_process_metrics = false;
48 
49  for (auto name : names)
50  {
51  if (name == "metric_queue_size")
52  {
53  metric_cache_max_size_ = pset.get<size_t>("metric_queue_size");
54  }
55  else if (name == "metric_queue_notify_size")
56  {
57  metric_cache_notify_size_ = pset.get<size_t>("metric_queue_notify_size");
58  }
59  else if (name == "metric_cache_size")
60  {
61  metric_cache_max_size_ = pset.get<size_t>("metric_cache_size");
62  }
63  else if (name == "metric_cache_notify_size")
64  {
65  metric_cache_notify_size_ = pset.get<size_t>("metric_cache_notify_size");
66  }
67  else if (name == "metric_send_maximum_delay_ms")
68  {
69  TLOG(TLVL_INFO) << "Setting metric_send_interval_ms_ to " << pset.get<int>("metric_send_maximum_delay_ms");
70  metric_send_interval_ms_ = pset.get<int>("metric_send_maximum_delay_ms");
71  }
72  else if (name == "metric_holdoff_us")
73  {
74  TLOG(TLVL_INFO) << "Setting metric_holdoff_us_ to " << pset.get<int>("metric_holdoff_us");
75  metric_holdoff_us_ = pset.get<int>("metric_holdoff_us");
76  }
77  else if (name == "send_system_metrics")
78  {
79  send_system_metrics = pset.get<bool>("send_system_metrics");
80  }
81  else if (name == "send_process_metrics")
82  {
83  send_process_metrics = pset.get<bool>("send_process_metrics");
84  }
85  else
86  {
87  try
88  {
89  TLOG(TLVL_DEBUG) << "Constructing metric plugin with name " << name;
90  fhicl::ParameterSet plugin_pset = pset.get<fhicl::ParameterSet>(name);
91  metric_plugins_.push_back(
92  makeMetricPlugin(plugin_pset.get<std::string>("metricPluginType", ""), plugin_pset, prefix_));
93  }
94  catch (const cet::exception& e)
95  {
96  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::initialize, error loading plugin with name " << name
97  << ", cet::exception object caught:" << e.explain_self();
98  }
99  catch (const boost::exception& e)
100  {
101  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::initialize, error loading plugin with name " << name
102  << ", boost::exception object caught: " << boost::diagnostic_information(e);
103  }
104  catch (const std::exception& e)
105  {
106  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::initialize, error loading plugin with name " << name
107  << ", std::exception caught: " << e.what();
108  }
109  catch (...)
110  {
111  TLOG(TLVL_ERROR) << "Unknown Exception caught in MetricManager::initialize, error loading plugin with name "
112  << name;
113  }
114  }
115  }
116 
117  if (send_system_metrics || send_process_metrics)
118  {
119  system_metric_collector_.reset(new SystemMetricCollector(send_process_metrics, send_system_metrics));
120  }
121 
122  initialized_ = true;
123 }
124 
126 {
127  std::lock_guard<std::mutex> lk(metric_mutex_);
128  if (!running_)
129  {
130  TLOG(TLVL_DEBUG) << "Starting MetricManager";
131  for (auto& metric : metric_plugins_)
132  {
133  if (!metric) continue;
134  try
135  {
136  metric->startMetrics();
137  TLOG(TLVL_INFO) << "Metric Plugin " << metric->getLibName() << " started.";
138  active_ = true;
139  }
140  catch (...)
141  {
142  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::do_start(), error starting plugin with name "
143  << metric->getLibName();
144  }
145  }
146  running_ = true;
147  startMetricLoop_();
148  }
149 }
150 
152 {
153  std::unique_lock<std::mutex> lk(metric_mutex_);
154  TLOG(TLVL_DEBUG) << "Stopping Metrics";
155  running_ = false;
156  metric_cv_.notify_all();
157  TLOG(TLVL_DEBUG) << "Joining Metric-Sending thread";
158  lk.unlock();
159  if (metric_sending_thread_.joinable()) metric_sending_thread_.join();
160  TLOG(TLVL_DEBUG) << "do_stop Complete";
161 }
162 
164 { /*do_stop();*/
165 }
167 { /*do_start();*/
168 }
169 
170 void artdaq::MetricManager::reinitialize(fhicl::ParameterSet const& pset, std::string const& prefix)
171 {
172  shutdown();
173  initialize(pset, prefix);
174 }
175 
177 {
178  TLOG(TLVL_DEBUG) << "MetricManager is shutting down...";
179  do_stop();
180 
181  std::lock_guard<std::mutex> lk(metric_mutex_);
182  if (initialized_)
183  {
184  initialized_ = false;
185  for (auto& i : metric_plugins_)
186  {
187  try
188  {
189  std::string name = i->getLibName();
190  i.reset(nullptr);
191  TLOG(TLVL_DEBUG) << "Metric Plugin " << name << " shutdown.";
192  }
193  catch (...)
194  {
195  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::shutdown(), error shutting down metric with name "
196  << i->getLibName();
197  }
198  }
199  metric_plugins_.clear();
200  }
201 }
202 
203 void artdaq::MetricManager::sendMetric(std::string const& name, std::string const& value, std::string const& unit,
204  int level, MetricMode mode, std::string const& metricPrefix,
205  bool useNameOverride)
206 {
207  if (!initialized_)
208  {
209  TLOG(TLVL_WARNING) << "Attempted to send metric when MetricManager has not yet been initialized!";
210  }
211  else if (!running_)
212  {
213  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
214  }
215  else if (active_)
216  {
217  {
218  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
219  metric_calls_++;
220  last_metric_received_ = std::chrono::steady_clock::now();
221  auto& cached = metric_cache_[name];
222  if (cached == nullptr)
223  {
224  metric_cache_[name].reset(new MetricData(name, value, unit, level, mode, metricPrefix, useNameOverride));
225  }
226  else
227  {
228  auto size = cached->DataPointCount;
229  if (size < metric_cache_max_size_)
230  {
231  if (size >= metric_cache_notify_size_)
232  {
233  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
234  << ".";
235  }
236  if (mode == MetricMode::LastPoint)
237  {
238  cached->StringValue = value;
239  cached->DataPointCount = 1;
240  }
241  else
242  {
243  cached->StringValue += " " + value;
244  cached->DataPointCount++;
245  }
246  }
247  else
248  {
249  TLOG(10) << "Rejecting metric because queue full";
250  missed_metric_calls_++;
251  }
252  }
253  }
254  metric_cv_.notify_all();
255  }
256 }
257 
258 void artdaq::MetricManager::sendMetric(std::string const& name, int const& value, std::string const& unit, int level,
259  MetricMode mode, std::string const& metricPrefix, bool useNameOverride)
260 {
261  if (!initialized_)
262  {
263  TLOG(TLVL_WARNING) << "Attempted to send metric when MetricManager has not yet been initialized!";
264  }
265  else if (!running_)
266  {
267  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
268  }
269  else if (active_)
270  {
271  {
272  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
273  metric_calls_++;
274  last_metric_received_ = std::chrono::steady_clock::now();
275  auto& cached = metric_cache_[name];
276  if (cached == nullptr)
277  {
278  metric_cache_[name].reset(new MetricData(name, value, unit, level, mode, metricPrefix, useNameOverride));
279  }
280  else
281  {
282  auto size = cached->DataPointCount;
283  if (size < metric_cache_max_size_)
284  {
285  if (size >= metric_cache_notify_size_)
286  {
287  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
288  << ".";
289  }
290  cached->AddPoint(value);
291  }
292  else
293  {
294  TLOG(10) << "Rejecting metric because queue full";
295  missed_metric_calls_++;
296  }
297  }
298  }
299  metric_cv_.notify_all();
300  }
301 }
302 
303 void artdaq::MetricManager::sendMetric(std::string const& name, double const& value, std::string const& unit, int level,
304  MetricMode mode, std::string const& metricPrefix, bool useNameOverride)
305 {
306  if (!initialized_)
307  {
308  TLOG(TLVL_WARNING) << "Attempted to send metric when MetricManager has not yet been initialized!";
309  }
310  else if (!running_)
311  {
312  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
313  }
314  else if (active_)
315  {
316  {
317  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
318  metric_calls_++;
319  last_metric_received_ = std::chrono::steady_clock::now();
320  auto& cached = metric_cache_[name];
321  if (cached == nullptr)
322  {
323  metric_cache_[name].reset(new MetricData(name, value, unit, level, mode, metricPrefix, useNameOverride));
324  }
325  else
326  {
327  auto size = cached->DataPointCount;
328  if (size < metric_cache_max_size_)
329  {
330  if (size >= metric_cache_notify_size_)
331  {
332  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
333  << ".";
334  }
335  cached->AddPoint(value);
336  }
337  else
338  {
339  TLOG(10) << "Rejecting metric because queue full";
340  missed_metric_calls_++;
341  }
342  }
343  }
344  metric_cv_.notify_all();
345  }
346 }
347 
348 void artdaq::MetricManager::sendMetric(std::string const& name, float const& value, std::string const& unit, int level,
349  MetricMode mode, std::string const& metricPrefix, bool useNameOverride)
350 {
351  if (!initialized_)
352  {
353  TLOG(TLVL_WARNING) << "Attempted to send metric when MetricManager has not yet been initialized!";
354  }
355  else if (!running_)
356  {
357  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
358  }
359  else if (active_)
360  {
361  {
362  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
363  metric_calls_++;
364  last_metric_received_ = std::chrono::steady_clock::now();
365  auto& cached = metric_cache_[name];
366  if (cached == nullptr)
367  {
368  metric_cache_[name].reset(new MetricData(name, value, unit, level, mode, metricPrefix, useNameOverride));
369  }
370  else
371  {
372  auto size = cached->DataPointCount;
373  if (size < metric_cache_max_size_)
374  {
375  if (size >= metric_cache_notify_size_)
376  {
377  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
378  << ".";
379  }
380  cached->AddPoint(value);
381  }
382  else
383  {
384  TLOG(10) << "Rejecting metric because queue full";
385  missed_metric_calls_++;
386  }
387  }
388  }
389  metric_cv_.notify_all();
390  }
391 }
392 
393 void artdaq::MetricManager::sendMetric(std::string const& name, long unsigned int const& value, std::string const& unit,
394  int level, MetricMode mode, std::string const& metricPrefix,
395  bool useNameOverride)
396 {
397  if (!initialized_)
398  {
399  TLOG(TLVL_WARNING) << "Attempted to send metric when MetricManager has not yet been initialized!";
400  }
401  else if (!running_)
402  {
403  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
404  }
405  else if (active_)
406  {
407  {
408  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
409  metric_calls_++;
410  last_metric_received_ = std::chrono::steady_clock::now();
411  auto& cached = metric_cache_[name];
412  if (cached == nullptr)
413  {
414  metric_cache_[name].reset(new MetricData(name, value, unit, level, mode, metricPrefix, useNameOverride));
415  }
416  else
417  {
418  auto size = cached->DataPointCount;
419  if (size < metric_cache_max_size_)
420  {
421  if (size >= metric_cache_notify_size_)
422  {
423  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
424  << ".";
425  }
426  cached->AddPoint(value);
427  }
428  else
429  {
430  TLOG(10) << "Rejecting metric because queue full";
431  missed_metric_calls_++;
432  }
433  }
434  }
435  metric_cv_.notify_all();
436  }
437 }
438 
439 void artdaq::MetricManager::startMetricLoop_()
440 {
441  if (metric_sending_thread_.joinable()) metric_sending_thread_.join();
442  boost::thread::attributes attrs;
443  attrs.set_stack_size(4096 * 2000); // 8000 KB
444  TLOG(TLVL_INFO) << "Starting Metric Sending Thread";
445  try
446  {
447  metric_sending_thread_ = boost::thread(attrs, boost::bind(&MetricManager::sendMetricLoop_, this));
448  }
449  catch (const boost::exception& e)
450  {
451  TLOG(TLVL_ERROR) << "Caught boost::exception starting Metric Sending thread: " << boost::diagnostic_information(e)
452  << ", errno=" << errno;
453  std::cerr << "Caught boost::exception starting Metric Sending thread: " << boost::diagnostic_information(e)
454  << ", errno=" << errno << std::endl;
455  exit(5);
456  }
457  TLOG(TLVL_INFO) << "Metric Sending thread started";
458 }
459 
461 {
462  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
463  for (auto& cache_entry : metric_cache_)
464  {
465  if (cache_entry.second->DataPointCount > 0) return false;
466  }
467 
468  return true;
469 }
470 
472 {
473  bool pluginsBusy = false;
474 
475  for (auto& p : metric_plugins_)
476  {
477  if (p->metricsPending())
478  {
479  pluginsBusy = true;
480  break;
481  }
482  }
483 
484  TLOG(TLVL_TRACE) << "Metric queue empty: " << metricQueueEmpty() << ", busy_: " << busy_ << ", Plugins busy: " << pluginsBusy;
485  return !metricQueueEmpty() || busy_ || pluginsBusy;
486 }
487 
488 size_t artdaq::MetricManager::metricQueueSize(std::string const& name)
489 {
490  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
491  size_t size = 0;
492  if (name == "")
493  {
494  for (auto& q : metric_cache_)
495  {
496  size += q.second->DataPointCount;
497  }
498  }
499  else
500  {
501  if (metric_cache_.count(name)) size = metric_cache_[name]->DataPointCount;
502  }
503 
504  return size;
505 }
506 
507 void artdaq::MetricManager::sendMetricLoop_()
508 {
509  TLOG(TLVL_INFO) << "sendMetricLoop_ START";
510  auto last_send_time = std::chrono::steady_clock::time_point();
511  while (running_)
512  {
513  TLOG(6) << "sendMetricLoop_: Entering Metric input wait loop";
514  while (metricQueueEmpty() && running_)
515  {
516  std::unique_lock<std::mutex> lk(metric_mutex_);
517  metric_cv_.wait_for(lk, std::chrono::milliseconds(100));
518  auto now = std::chrono::steady_clock::now();
519  if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_send_time).count() >
520  metric_send_interval_ms_)
521  {
522  TLOG(6) << "sendMetricLoop_: Metric send interval exceeded: Sending metrics";
523  if (std::chrono::duration_cast<std::chrono::microseconds>(now - last_metric_received_).count() < metric_holdoff_us_)
524  {
525  usleep(metric_holdoff_us_);
526  }
527  for (auto& metric : metric_plugins_)
528  {
529  if (metric) metric->sendMetrics();
530  }
531  last_send_time = now;
532  }
533  }
534  if (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - last_metric_received_).count() < metric_holdoff_us_)
535  {
536  usleep(metric_holdoff_us_);
537  }
538 
539  TLOG(6) << "sendMetricLoop_: After Metric input wait loop";
540  busy_ = true;
541  auto processing_start = std::chrono::steady_clock::now();
542  auto temp_list = std::list<std::unique_ptr<MetricData>>();
543  {
544  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
545 
546  for (auto& q : metric_cache_)
547  {
548  temp_list.emplace_back(new MetricData(*q.second));
549  q.second->Reset();
550  }
551  }
552 
553  auto calls = metric_calls_.exchange(0);
554  temp_list.emplace_back(
555  new MetricData("Metric Calls", calls, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
556 
557  auto missed = missed_metric_calls_.exchange(0);
558  temp_list.emplace_back(
559  new MetricData("Missed Metric Calls", missed, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
560 
561  TLOG(TLVL_TRACE) << "There are " << temp_list.size() << " Metrics to process (" << calls << " calls, " << missed
562  << " missed)";
563 
564  if (system_metric_collector_ != nullptr)
565  {
566  TLOG(TLVL_TRACE) << "Collecting System metrics (CPU, RAM, Network)";
567  auto systemMetrics = system_metric_collector_->SendMetrics();
568  for (auto& m : systemMetrics) { temp_list.emplace_back(std::move(m)); }
569  }
570 
571  TLOG(6) << "sendMetricLoop_: Before processing temp_list";
572  while (temp_list.size() > 0)
573  {
574  auto data_ = std::move(temp_list.front());
575  temp_list.pop_front();
576  if (data_->Type == MetricType::InvalidMetric) continue;
577  if (!data_->UseNameOverride)
578  {
579  if (data_->MetricPrefix.size() > 0)
580  {
581  data_->Name = prefix_ + "." + data_->MetricPrefix + "." + data_->Name;
582  }
583  else
584  {
585  data_->Name = prefix_ + "." + data_->Name;
586  }
587  }
588 
589  for (auto& metric : metric_plugins_)
590  {
591  if (!metric) continue;
592  if (metric->IsLevelEnabled(data_->Level))
593  {
594  try
595  {
596  metric->addMetricData(data_);
597  last_send_time = std::chrono::steady_clock::now();
598  }
599  catch (...)
600  {
601  TLOG(TLVL_ERROR) << "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
602  << metric->getLibName();
603  }
604  }
605  }
606  }
607 
608  TLOG(6) << "sendMetricLoop_: Before sending metrics";
609  for (auto& metric : metric_plugins_)
610  {
611  if (!metric) continue;
612  metric->sendMetrics(false, processing_start);
613  }
614 
615  // Limit rate of metrics going to plugins
616  TLOG(6) << "sendMetricLoop_: End of working loop";
617  busy_ = false;
618  usleep(10000);
619  }
620 
621  busy_ = true;
622  auto temp_list = std::list<std::unique_ptr<MetricData>>();
623  {
624  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
625 
626  for (auto& q : metric_cache_)
627  {
628  if (q.second != nullptr && q.second->DataPointCount > 0)
629  {
630  temp_list.emplace_back(new MetricData(*q.second));
631  q.second->Reset();
632  }
633  }
634  //metric_cache_.clear();
635  }
636 
637  auto calls = metric_calls_.exchange(0);
638  temp_list.emplace_back(
639  new MetricData("Metric Calls", calls, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
640 
641  auto missed = missed_metric_calls_.exchange(0);
642  temp_list.emplace_back(
643  new MetricData("Missed Metric Calls", missed, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
644 
645  TLOG(TLVL_TRACE) << "There are " << temp_list.size() << " Metrics to process (" << calls << " calls, " << missed
646  << " missed)";
647 
648  while (temp_list.size() > 0)
649  {
650  auto data_ = std::move(temp_list.front());
651  temp_list.pop_front();
652  if (data_->Type == MetricType::InvalidMetric) continue;
653  if (!data_->UseNameOverride)
654  {
655  if (data_->MetricPrefix.size() > 0)
656  {
657  data_->Name = prefix_ + "." + data_->MetricPrefix + "." + data_->Name;
658  }
659  else
660  {
661  data_->Name = prefix_ + "." + data_->Name;
662  }
663  }
664 
665  for (auto& metric : metric_plugins_)
666  {
667  if (!metric) continue;
668  if (metric->IsLevelEnabled(data_->Level))
669  {
670  try
671  {
672  metric->addMetricData(data_);
673  last_send_time = std::chrono::steady_clock::now();
674  }
675  catch (...)
676  {
677  TLOG(TLVL_ERROR) << "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
678  << metric->getLibName();
679  }
680  }
681  }
682  }
683 
684  for (auto& metric : metric_plugins_)
685  {
686  if (!metric) continue;
687  try
688  {
689  metric->stopMetrics();
690  TLOG(TLVL_DEBUG) << "Metric Plugin " << metric->getLibName() << " stopped.";
691  }
692  catch (...)
693  {
694  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::do_stop(), error stopping plugin with name "
695  << metric->getLibName();
696  }
697  }
698  busy_ = false;
699  TLOG(TLVL_DEBUG) << "MetricManager has been stopped.";
700 }
void shutdown()
Call the destructors for all configured MetricPlugin instances.
void initialize(fhicl::ParameterSet const &pset, std::string const &prefix="")
Initialize the MetricPlugin instances.
void sendMetric(std::string const &name, std::string const &value, std::string const &unit, int level, MetricMode mode, std::string const &metricPrefix="", bool useNameOverride=false)
Send a metric with the given parameters to any MetricPlugins with a threshold level &gt;= to level...
bool metricManagerBusy()
Determine whether the MetricManager or any of its plugins are currently processing metrics...
size_t metricQueueSize(std::string const &name="")
Return the size of the named metric queue
void reinitialize(fhicl::ParameterSet const &pset, std::string const &prefix="")
Reinitialize all MetricPlugin Instances.
Report the sum of all values. Use for counters to report accurate results.
MetricManager()
Construct an instance of the MetricManager class.
void do_start()
Perform startup actions for each configured MetricPlugin.
void do_stop()
Stop sending metrics to the MetricPlugin instances.
virtual ~MetricManager() noexcept
MetricManager destructor.
std::unique_ptr< MetricPlugin > makeMetricPlugin(std::string const &generator_plugin_spec, fhicl::ParameterSet const &ps, std::string const &app_name)
Load a given MetricPlugin and return a pointer to it.
over. Use to create rates from counters.
Report only the last value recorded. Useful for event counters, run numbers, etc. ...
MetricMode
The Mode of the metric indicates how multiple metric values should be combined within a reporting int...
Definition: MetricData.hh:29
Collects metrics from the system, using proc filesystem or kernel API calls
Small structure used to hold a metric data point before sending to the metric plugins ...
Definition: MetricData.hh:64
Default, invalid value.
void do_resume()
Resume metric sending. Currently a No-Op.
bool metricQueueEmpty()
Returns whether the metric queue is completely empty
void do_pause()
Pause metric sending. Currently a No-Op.