artdaq_utilities  v1_05_03
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  auto lk = std::unique_lock<std::mutex>(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  auto lk = std::unique_lock<std::mutex>(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  auto lk = std::unique_lock<std::mutex>(metric_mutex_);
182  if (initialized_)
183  {
184  for (auto& i : metric_plugins_)
185  {
186  try
187  {
188  std::string name = i->getLibName();
189  i.reset(nullptr);
190  TLOG(TLVL_DEBUG) << "Metric Plugin " << name << " shutdown.";
191  }
192  catch (...)
193  {
194  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::shutdown(), error shutting down metric with name "
195  << i->getLibName();
196  }
197  }
198  metric_plugins_.clear();
199  initialized_ = false;
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::unique_lock<std::mutex> lk(metric_cache_mutex_);
219  metric_calls_++;
220  last_metric_received_ = std::chrono::steady_clock::now();
221  if (!metric_cache_.count(name) || metric_cache_[name] == nullptr)
222  {
223  metric_cache_[name] =
224  std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
225  }
226  else
227  {
228  auto size = metric_cache_[name]->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  metric_cache_[name]->StringValue = value;
239  metric_cache_[name]->DataPointCount = 1;
240  }
241  else
242  {
243  metric_cache_[name]->StringValue += " " + value;
244  metric_cache_[name]->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::unique_lock<std::mutex> lk(metric_cache_mutex_);
273  metric_calls_++;
274  last_metric_received_ = std::chrono::steady_clock::now();
275  if (!metric_cache_.count(name) || metric_cache_[name] == nullptr)
276  {
277  metric_cache_[name] =
278  std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
279  }
280  else
281  {
282  auto size = metric_cache_[name]->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  metric_cache_[name]->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::unique_lock<std::mutex> lk(metric_cache_mutex_);
318  metric_calls_++;
319  last_metric_received_ = std::chrono::steady_clock::now();
320  if (!metric_cache_.count(name) || metric_cache_[name] == nullptr)
321  {
322  metric_cache_[name] =
323  std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
324  }
325  else
326  {
327  auto size = metric_cache_[name]->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  metric_cache_[name]->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::unique_lock<std::mutex> lk(metric_cache_mutex_);
363  metric_calls_++;
364  last_metric_received_ = std::chrono::steady_clock::now();
365  if (!metric_cache_.count(name) || metric_cache_[name] == nullptr)
366  {
367  metric_cache_[name] =
368  std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
369  }
370  else
371  {
372  auto size = metric_cache_[name]->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  metric_cache_[name]->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::unique_lock<std::mutex> lk(metric_cache_mutex_);
409  metric_calls_++;
410  last_metric_received_ = std::chrono::steady_clock::now();
411  if (!metric_cache_.count(name) || metric_cache_[name] == nullptr)
412  {
413  metric_cache_[name] =
414  std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
415  }
416  else
417  {
418  auto size = metric_cache_[name]->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  metric_cache_[name]->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::unique_lock<std::mutex> lk(metric_cache_mutex_);
463  return metric_cache_.size() == 0;
464 }
465 
467 {
468  bool pluginsBusy = false;
469 
470  for (auto& p : metric_plugins_)
471  {
472  if (p->metricsPending())
473  {
474  pluginsBusy = true;
475  break;
476  }
477  }
478 
479  TLOG(TLVL_TRACE) << "Metric queue empty: " << metricQueueEmpty() << ", busy_: " << busy_ << ", Plugins busy: " << pluginsBusy;
480  return !metricQueueEmpty() || busy_ || pluginsBusy;
481 }
482 
483 size_t artdaq::MetricManager::metricQueueSize(std::string const& name)
484 {
485  std::unique_lock<std::mutex> lk(metric_cache_mutex_);
486  size_t size = 0;
487  if (name == "")
488  {
489  for (auto& q : metric_cache_)
490  {
491  size += q.second->DataPointCount;
492  }
493  }
494  else
495  {
496  if (metric_cache_.count(name)) size = metric_cache_[name]->DataPointCount;
497  }
498 
499  return size;
500 }
501 
502 void artdaq::MetricManager::sendMetricLoop_()
503 {
504  TLOG(TLVL_INFO) << "sendMetricLoop_ START";
505  auto last_send_time = std::chrono::steady_clock::time_point();
506  while (running_)
507  {
508  TLOG(6) << "sendMetricLoop_: Entering Metric input wait loop";
509  while (metricQueueEmpty() && running_)
510  {
511  std::unique_lock<std::mutex> lk(metric_mutex_);
512  metric_cv_.wait_for(lk, std::chrono::milliseconds(100));
513  auto now = std::chrono::steady_clock::now();
514  if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_send_time).count() >
515  metric_send_interval_ms_)
516  {
517  TLOG(6) << "sendMetricLoop_: Metric send interval exceeded: Sending metrics";
518  if (std::chrono::duration_cast<std::chrono::microseconds>(now - last_metric_received_).count() < metric_holdoff_us_)
519  {
520  usleep(metric_holdoff_us_);
521  }
522  for (auto& metric : metric_plugins_)
523  {
524  if (metric) metric->sendMetrics();
525  }
526  last_send_time = now;
527  }
528  }
529  if (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - last_metric_received_).count() < metric_holdoff_us_)
530  {
531  usleep(metric_holdoff_us_);
532  }
533 
534  TLOG(6) << "sendMetricLoop_: After Metric input wait loop";
535  busy_ = true;
536  auto processing_start = std::chrono::steady_clock::now();
537  auto temp_list = std::list<std::unique_ptr<MetricData>>();
538  {
539  std::unique_lock<std::mutex> lk(metric_cache_mutex_);
540 
541  for (auto& q : metric_cache_)
542  {
543  temp_list.emplace_back(std::move(q.second));
544  }
545  metric_cache_.clear();
546 
547  auto calls = metric_calls_.exchange(0);
548  temp_list.emplace_back(
549  new MetricData("Metric Calls", calls, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
550 
551  auto missed = missed_metric_calls_.exchange(0);
552  temp_list.emplace_back(
553  new MetricData("Missed Metric Calls", missed, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
554 
555  TLOG(TLVL_TRACE) << "There are " << temp_list.size() << " Metrics to process (" << calls << " calls, " << missed
556  << " missed)";
557 
558  if (system_metric_collector_ != nullptr)
559  {
560  TLOG(TLVL_TRACE) << "Collecting System metrics (CPU, RAM, Network)";
561  auto systemMetrics = system_metric_collector_->SendMetrics();
562  for (auto& m : systemMetrics) { temp_list.emplace_back(std::move(m)); }
563  }
564  }
565 
566  TLOG(6) << "sendMetricLoop_: Before processing temp_list";
567  while (temp_list.size() > 0)
568  {
569  auto data_ = std::move(temp_list.front());
570  temp_list.pop_front();
571  if (data_->Type == MetricType::InvalidMetric) continue;
572  if (!data_->UseNameOverride)
573  {
574  if (data_->MetricPrefix.size() > 0)
575  {
576  data_->Name = prefix_ + "." + data_->MetricPrefix + "." + data_->Name;
577  }
578  else
579  {
580  data_->Name = prefix_ + "." + data_->Name;
581  }
582  }
583 
584  for (auto& metric : metric_plugins_)
585  {
586  if (!metric) continue;
587  if (metric->IsLevelEnabled(data_->Level))
588  {
589  try
590  {
591  metric->addMetricData(data_);
592  last_send_time = std::chrono::steady_clock::now();
593  }
594  catch (...)
595  {
596  TLOG(TLVL_ERROR) << "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
597  << metric->getLibName();
598  }
599  }
600  }
601  }
602 
603  TLOG(6) << "sendMetricLoop_: Before sending metrics";
604  for (auto& metric : metric_plugins_)
605  {
606  if (!metric) continue;
607  metric->sendMetrics(false, processing_start);
608  }
609 
610  // Limit rate of metrics going to plugins
611  TLOG(6) << "sendMetricLoop_: End of working loop";
612  busy_ = false;
613  usleep(10000);
614  }
615 
616  busy_ = true;
617  auto temp_list = std::list<std::unique_ptr<MetricData>>();
618  {
619  std::unique_lock<std::mutex> lk(metric_cache_mutex_);
620 
621  for (auto& q : metric_cache_)
622  {
623  temp_list.emplace_back(std::move(q.second));
624  }
625  metric_cache_.clear();
626 
627  auto calls = metric_calls_.exchange(0);
628  temp_list.emplace_back(
629  new MetricData("Metric Calls", calls, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
630 
631  auto missed = missed_metric_calls_.exchange(0);
632  temp_list.emplace_back(
633  new MetricData("Missed Metric Calls", missed, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
634 
635  TLOG(TLVL_TRACE) << "There are " << temp_list.size() << " Metrics to process (" << calls << " calls, " << missed
636  << " missed)";
637  }
638 
639  while (temp_list.size() > 0)
640  {
641  auto data_ = std::move(temp_list.front());
642  temp_list.pop_front();
643  if (data_->Type == MetricType::InvalidMetric) continue;
644  if (!data_->UseNameOverride)
645  {
646  if (data_->MetricPrefix.size() > 0)
647  {
648  data_->Name = prefix_ + "." + data_->MetricPrefix + "." + data_->Name;
649  }
650  else
651  {
652  data_->Name = prefix_ + "." + data_->Name;
653  }
654  }
655 
656  for (auto& metric : metric_plugins_)
657  {
658  if (!metric) continue;
659  if (metric->IsLevelEnabled(data_->Level))
660  {
661  try
662  {
663  metric->addMetricData(data_);
664  last_send_time = std::chrono::steady_clock::now();
665  }
666  catch (...)
667  {
668  TLOG(TLVL_ERROR) << "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
669  << metric->getLibName();
670  }
671  }
672  }
673  }
674 
675  for (auto& metric : metric_plugins_)
676  {
677  if (!metric) continue;
678  try
679  {
680  metric->stopMetrics();
681  TLOG(TLVL_DEBUG) << "Metric Plugin " << metric->getLibName() << " stopped.";
682  }
683  catch (...)
684  {
685  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::do_stop(), error stopping plugin with name "
686  << metric->getLibName();
687  }
688  }
689  busy_ = false;
690  TLOG(TLVL_DEBUG) << "MetricManager has been stopped.";
691 }
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.
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
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.