artdaq_utilities  v1_05_11
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 <pthread.h>
16 #include <boost/exception/all.hpp>
17 #include <chrono>
18 #include <memory>
19 
21  : metric_plugins_(0)
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 
30 artdaq::MetricManager::~MetricManager() noexcept { shutdown(); }
31 
32 void artdaq::MetricManager::initialize(fhicl::ParameterSet const& pset, std::string const& prefix)
33 {
34  prefix_ = prefix;
35  if (initialized_)
36  {
37  shutdown();
38  }
39  TLOG(TLVL_INFO) << "Configuring metrics with parameter set: " << pset.to_string();
40 
41  std::vector<std::string> names = pset.get_names();
42 
43  metric_plugins_.clear();
44  bool send_system_metrics = false;
45  bool send_process_metrics = false;
46 
47  for (const auto& name : names)
48  {
49  if (name == "metric_queue_size")
50  {
51  metric_cache_max_size_ = pset.get<size_t>("metric_queue_size");
52  }
53  else if (name == "metric_queue_notify_size")
54  {
55  metric_cache_notify_size_ = pset.get<size_t>("metric_queue_notify_size");
56  }
57  else if (name == "metric_cache_size")
58  {
59  metric_cache_max_size_ = pset.get<size_t>("metric_cache_size");
60  }
61  else if (name == "metric_cache_notify_size")
62  {
63  metric_cache_notify_size_ = pset.get<size_t>("metric_cache_notify_size");
64  }
65  else if (name == "metric_send_maximum_delay_ms")
66  {
67  TLOG(TLVL_INFO) << "Setting metric_send_interval_ms_ to " << pset.get<int>("metric_send_maximum_delay_ms");
68  metric_send_interval_ms_ = pset.get<int>("metric_send_maximum_delay_ms");
69  }
70  else if (name == "metric_holdoff_us")
71  {
72  TLOG(TLVL_INFO) << "Setting metric_holdoff_us_ to " << pset.get<int>("metric_holdoff_us");
73  metric_holdoff_us_ = pset.get<int>("metric_holdoff_us");
74  }
75  else if (name == "send_system_metrics")
76  {
77  send_system_metrics = pset.get<bool>("send_system_metrics");
78  }
79  else if (name == "send_process_metrics")
80  {
81  send_process_metrics = pset.get<bool>("send_process_metrics");
82  }
83  else
84  {
85  try
86  {
87  TLOG(TLVL_DEBUG) << "Constructing metric plugin with name " << name;
88  auto plugin_pset = pset.get<fhicl::ParameterSet>(name);
89  metric_plugins_.push_back(
90  makeMetricPlugin(plugin_pset.get<std::string>("metricPluginType", ""), plugin_pset, prefix_));
91  }
92  catch (const cet::exception& e)
93  {
94  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::initialize, error loading plugin with name " << name
95  << ", cet::exception object caught:" << e.explain_self();
96  }
97  catch (const boost::exception& e)
98  {
99  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::initialize, error loading plugin with name " << name
100  << ", boost::exception object caught: " << boost::diagnostic_information(e);
101  }
102  catch (const std::exception& e)
103  {
104  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::initialize, error loading plugin with name " << name
105  << ", std::exception caught: " << e.what();
106  }
107  catch (...)
108  {
109  TLOG(TLVL_ERROR) << "Unknown Exception caught in MetricManager::initialize, error loading plugin with name "
110  << name;
111  }
112  }
113  }
114 
115  if (send_system_metrics || send_process_metrics)
116  {
117  system_metric_collector_ = std::make_unique<SystemMetricCollector>(send_process_metrics, send_system_metrics);
118  }
119 
120  initialized_ = true;
121 }
122 
124 {
125  std::lock_guard<std::mutex> lk(metric_mutex_);
126  if (!running_)
127  {
128  TLOG(TLVL_DEBUG) << "Starting MetricManager";
129  for (auto& metric : metric_plugins_)
130  {
131  if (!metric)
132  {
133  continue;
134  }
135  try
136  {
137  metric->startMetrics();
138  TLOG(TLVL_INFO) << "Metric Plugin " << metric->getLibName() << " started.";
139  active_ = true;
140  }
141  catch (...)
142  {
143  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::do_start(), error starting plugin with name "
144  << metric->getLibName();
145  }
146  }
147  running_ = true;
148  startMetricLoop_();
149  }
150 }
151 
153 {
154  std::unique_lock<std::mutex> lk(metric_mutex_);
155  TLOG(TLVL_DEBUG) << "Stopping Metrics";
156  running_ = false;
157  metric_cv_.notify_all();
158  TLOG(TLVL_DEBUG) << "Joining Metric-Sending thread";
159  lk.unlock();
160  try
161  {
162  if (metric_sending_thread_.joinable())
163  {
164  metric_sending_thread_.join();
165  }
166  }
167  catch (...)
168  {
169  // IGNORED
170  }
171  TLOG(TLVL_DEBUG) << "do_stop Complete";
172 }
173 
175 { /*do_stop();*/
176 }
178 { /*do_start();*/
179 }
180 
181 void artdaq::MetricManager::reinitialize(fhicl::ParameterSet const& pset, std::string const& prefix)
182 {
183  shutdown();
184  initialize(pset, prefix);
185 }
186 
188 {
189  TLOG(TLVL_DEBUG) << "MetricManager is shutting down...";
190  do_stop();
191 
192  std::lock_guard<std::mutex> lk(metric_mutex_);
193  if (initialized_)
194  {
195  initialized_ = false;
196  for (auto& i : metric_plugins_)
197  {
198  try
199  {
200  std::string name = i->getLibName();
201  i.reset(nullptr);
202  TLOG(TLVL_DEBUG) << "Metric Plugin " << name << " shutdown.";
203  }
204  catch (...)
205  {
206  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::shutdown(), error shutting down metric with name "
207  << i->getLibName();
208  }
209  }
210  metric_plugins_.clear();
211  }
212 }
213 
214 void artdaq::MetricManager::sendMetric(std::string const& name, std::string const& value, std::string const& unit,
215  int level, MetricMode mode, std::string const& metricPrefix,
216  bool useNameOverride)
217 {
218  if (!initialized_)
219  {
220  TLOG(TLVL_WARNING) << "Attempted to send metric " << name << " when MetricManager has not yet been initialized!";
221  }
222  else if (!running_)
223  {
224  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
225  }
226  else if (active_)
227  {
228  {
229  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
230  metric_calls_++;
231  last_metric_received_ = std::chrono::steady_clock::now();
232  auto& cached = metric_cache_[name];
233  if (cached == nullptr)
234  {
235  metric_cache_[name] = std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
236  }
237  else
238  {
239  auto size = cached->DataPointCount;
240  if (size < metric_cache_max_size_)
241  {
242  if (size >= metric_cache_notify_size_)
243  {
244  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
245  << ".";
246  }
247  if (mode == MetricMode::LastPoint)
248  {
249  cached->StringValue = value;
250  cached->DataPointCount = 1;
251  }
252  else
253  {
254  cached->StringValue += " " + value;
255  cached->DataPointCount++;
256  }
257  }
258  else
259  {
260  TLOG(10) << "Rejecting metric because queue full";
261  missed_metric_calls_++;
262  }
263  }
264  }
265  metric_cv_.notify_all();
266  }
267 }
268 
269 void artdaq::MetricManager::sendMetric(std::string const& name, int const& value, std::string const& unit, int level,
270  MetricMode mode, std::string const& metricPrefix, bool useNameOverride)
271 {
272  if (!initialized_)
273  {
274  TLOG(TLVL_WARNING) << "Attempted to send metric " << name << " when MetricManager has not yet been initialized!";
275  }
276  else if (!running_)
277  {
278  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
279  }
280  else if (active_)
281  {
282  {
283  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
284  metric_calls_++;
285  last_metric_received_ = std::chrono::steady_clock::now();
286  auto& cached = metric_cache_[name];
287  if (cached == nullptr)
288  {
289  metric_cache_[name] = std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
290  }
291  else
292  {
293  auto size = cached->DataPointCount;
294  if (size < metric_cache_max_size_)
295  {
296  if (size >= metric_cache_notify_size_)
297  {
298  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
299  << ".";
300  }
301  cached->AddPoint(value);
302  }
303  else
304  {
305  TLOG(10) << "Rejecting metric because queue full";
306  missed_metric_calls_++;
307  }
308  }
309  }
310  metric_cv_.notify_all();
311  }
312 }
313 
314 void artdaq::MetricManager::sendMetric(std::string const& name, double const& value, std::string const& unit, int level,
315  MetricMode mode, std::string const& metricPrefix, bool useNameOverride)
316 {
317  if (!initialized_)
318  {
319  TLOG(TLVL_WARNING) << "Attempted to send metric " << name << " when MetricManager has not yet been initialized!";
320  }
321  else if (!running_)
322  {
323  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
324  }
325  else if (active_)
326  {
327  {
328  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
329  metric_calls_++;
330  last_metric_received_ = std::chrono::steady_clock::now();
331  auto& cached = metric_cache_[name];
332  if (cached == nullptr)
333  {
334  metric_cache_[name] = std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
335  }
336  else
337  {
338  auto size = cached->DataPointCount;
339  if (size < metric_cache_max_size_)
340  {
341  if (size >= metric_cache_notify_size_)
342  {
343  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
344  << ".";
345  }
346  cached->AddPoint(value);
347  }
348  else
349  {
350  TLOG(10) << "Rejecting metric because queue full";
351  missed_metric_calls_++;
352  }
353  }
354  }
355  metric_cv_.notify_all();
356  }
357 }
358 
359 void artdaq::MetricManager::sendMetric(std::string const& name, float const& value, std::string const& unit, int level,
360  MetricMode mode, std::string const& metricPrefix, bool useNameOverride)
361 {
362  if (!initialized_)
363  {
364  TLOG(TLVL_WARNING) << "Attempted to send metric " << name << " when MetricManager has not yet been initialized!";
365  }
366  else if (!running_)
367  {
368  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
369  }
370  else if (active_)
371  {
372  {
373  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
374  metric_calls_++;
375  last_metric_received_ = std::chrono::steady_clock::now();
376  auto& cached = metric_cache_[name];
377  if (cached == nullptr)
378  {
379  metric_cache_[name] = std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
380  }
381  else
382  {
383  auto size = cached->DataPointCount;
384  if (size < metric_cache_max_size_)
385  {
386  if (size >= metric_cache_notify_size_)
387  {
388  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
389  << ".";
390  }
391  cached->AddPoint(value);
392  }
393  else
394  {
395  TLOG(10) << "Rejecting metric because queue full";
396  missed_metric_calls_++;
397  }
398  }
399  }
400  metric_cv_.notify_all();
401  }
402 }
403 
404 void artdaq::MetricManager::sendMetric(std::string const& name, uint64_t const& value, std::string const& unit,
405  int level, MetricMode mode, std::string const& metricPrefix,
406  bool useNameOverride)
407 {
408  if (!initialized_)
409  {
410  TLOG(TLVL_WARNING) << "Attempted to send metric " << name << " when MetricManager has not yet been initialized!";
411  }
412  else if (!running_)
413  {
414  TLOG(TLVL_INFO) << "Attempted to send metric when MetricManager stopped!";
415  }
416  else if (active_)
417  {
418  {
419  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
420  metric_calls_++;
421  last_metric_received_ = std::chrono::steady_clock::now();
422  auto& cached = metric_cache_[name];
423  if (cached == nullptr)
424  {
425  metric_cache_[name] = std::make_unique<MetricData>(name, value, unit, level, mode, metricPrefix, useNameOverride);
426  }
427  else
428  {
429  auto size = cached->DataPointCount;
430  if (size < metric_cache_max_size_)
431  {
432  if (size >= metric_cache_notify_size_)
433  {
434  TLOG(9) << "Metric cache is at size " << size << " of " << metric_cache_max_size_ << " for metric " << name
435  << ".";
436  }
437  cached->AddPoint(value);
438  }
439  else
440  {
441  TLOG(10) << "Rejecting metric because queue full";
442  missed_metric_calls_++;
443  }
444  }
445  }
446  metric_cv_.notify_all();
447  }
448 }
449 
450 void artdaq::MetricManager::startMetricLoop_()
451 {
452  if (metric_sending_thread_.joinable())
453  {
454  metric_sending_thread_.join();
455  }
456  boost::thread::attributes attrs;
457  attrs.set_stack_size(4096 * 2000); // 8000 KB
458  TLOG(TLVL_INFO) << "Starting Metric Sending Thread";
459  try
460  {
461  metric_sending_thread_ = boost::thread(attrs, boost::bind(&MetricManager::sendMetricLoop_, this));
462 
463  char tname[16]; // Size 16 - see man page pthread_setname_np(3) and/or prctl(2)
464  snprintf(tname, sizeof(tname)-1, "%s", "MetricSend"); // NOLINT
465  tname[sizeof(tname)-1] = '\0'; // assure term. snprintf is not too evil :)
466  auto handle = metric_sending_thread_.native_handle();
467  pthread_setname_np(handle, tname);
468  }
469  catch (const boost::exception& e)
470  {
471  TLOG(TLVL_ERROR) << "Caught boost::exception starting Metric Sending thread: " << boost::diagnostic_information(e)
472  << ", errno=" << errno;
473  std::cerr << "Caught boost::exception starting Metric Sending thread: " << boost::diagnostic_information(e)
474  << ", errno=" << errno << std::endl;
475  exit(5);
476  }
477  TLOG(TLVL_INFO) << "Metric Sending thread started";
478 }
479 
481 {
482  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
483  for (auto& cache_entry : metric_cache_)
484  {
485  if (cache_entry.second->DataPointCount > 0)
486  {
487  return false;
488  }
489  }
490 
491  return true;
492 }
493 
495 {
496  bool pluginsBusy = false;
497 
498  for (auto& p : metric_plugins_)
499  {
500  if (p->metricsPending())
501  {
502  pluginsBusy = true;
503  break;
504  }
505  }
506 
507  TLOG(TLVL_TRACE) << "Metric queue empty: " << metricQueueEmpty() << ", busy_: " << busy_ << ", Plugins busy: " << pluginsBusy;
508  return !metricQueueEmpty() || busy_ || pluginsBusy;
509 }
510 
511 size_t artdaq::MetricManager::metricQueueSize(std::string const& name)
512 {
513  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
514  size_t size = 0;
515  if (name.empty())
516  {
517  for (auto& q : metric_cache_)
518  {
519  size += q.second->DataPointCount;
520  }
521  }
522  else
523  {
524  if (metric_cache_.count(name) != 0u)
525  {
526  size = metric_cache_[name]->DataPointCount;
527  }
528  }
529 
530  return size;
531 }
532 
533 void artdaq::MetricManager::sendMetricLoop_()
534 {
535  TLOG(TLVL_INFO) << "sendMetricLoop_ START";
536  auto last_send_time = std::chrono::steady_clock::time_point();
537  while (running_)
538  {
539  TLOG(TLVL_DEBUG + 3) << "sendMetricLoop_: Entering Metric input wait loop";
540  while (metricQueueEmpty() && running_)
541  {
542  std::unique_lock<std::mutex> lk(metric_mutex_);
543  metric_cv_.wait_for(lk, std::chrono::milliseconds(100));
544  auto now = std::chrono::steady_clock::now();
545  if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_send_time).count() >
546  metric_send_interval_ms_)
547  {
548  TLOG(TLVL_DEBUG + 3) << "sendMetricLoop_: Metric send interval exceeded: Sending metrics";
549  {
550  std::unique_lock<std::mutex> lk(metric_cache_mutex_); // last_metric_received_ is protected by metric_cache_mutex_
551  if (std::chrono::duration_cast<std::chrono::microseconds>(now - last_metric_received_).count() < metric_holdoff_us_)
552  {
553  lk.unlock();
554  usleep(metric_holdoff_us_);
555  }
556  }
557  for (auto& metric : metric_plugins_)
558  {
559  if (metric)
560  {
561  metric->sendMetrics();
562  }
563  }
564  last_send_time = now;
565  }
566  }
567  {
568  std::unique_lock<std::mutex> lk(metric_cache_mutex_); // last_metric_received_ is protected by metric_cache_mutex_
569  if (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - last_metric_received_).count() < metric_holdoff_us_)
570  {
571  lk.unlock();
572  usleep(metric_holdoff_us_);
573  }
574  }
575 
576  TLOG(TLVL_DEBUG + 3) << "sendMetricLoop_: After Metric input wait loop";
577  busy_ = true;
578  auto processing_start = std::chrono::steady_clock::now();
579  auto temp_list = std::list<std::unique_ptr<MetricData>>();
580  {
581  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
582 
583  for (auto& q : metric_cache_)
584  {
585  if (q.second != nullptr && q.second->DataPointCount > 0)
586  {
587  temp_list.emplace_back(new MetricData(*q.second));
588  q.second->Reset();
589  }
590  }
591  }
592 
593  auto calls = metric_calls_.exchange(0);
594  temp_list.emplace_back(
595  new MetricData("Metric Calls", calls, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
596 
597  auto missed = missed_metric_calls_.exchange(0);
598  temp_list.emplace_back(
599  new MetricData("Missed Metric Calls", missed, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
600 
601  TLOG(TLVL_TRACE) << "There are " << temp_list.size() << " Metrics to process (" << calls << " calls, " << missed
602  << " missed)";
603 
604  if (system_metric_collector_ != nullptr)
605  {
606  TLOG(TLVL_TRACE) << "Collecting System metrics (CPU, RAM, Network)";
607  auto systemMetrics = system_metric_collector_->SendMetrics();
608  for (auto& m : systemMetrics) { temp_list.emplace_back(std::move(m)); }
609  }
610 
611  TLOG(TLVL_DEBUG + 3) << "sendMetricLoop_: Before processing temp_list";
612  while (!temp_list.empty())
613  {
614  auto data_ = std::move(temp_list.front());
615  temp_list.pop_front();
616  if (data_->Type == MetricType::InvalidMetric)
617  {
618  continue;
619  }
620  if (!data_->UseNameOverride)
621  {
622  if (!data_->MetricPrefix.empty())
623  {
624  data_->Name = prefix_ + "." + data_->MetricPrefix + "." + data_->Name;
625  }
626  else
627  {
628  data_->Name = prefix_ + "." + data_->Name;
629  }
630  }
631 
632  for (auto& metric : metric_plugins_)
633  {
634  if (!metric)
635  {
636  continue;
637  }
638  if (metric->IsLevelEnabled(data_->Level))
639  {
640  try
641  {
642  metric->addMetricData(data_);
643  last_send_time = std::chrono::steady_clock::now();
644  }
645  catch (...)
646  {
647  TLOG(TLVL_ERROR) << "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
648  << metric->getLibName();
649  }
650  }
651  }
652  }
653 
654  TLOG(TLVL_DEBUG + 3) << "sendMetricLoop_: Before sending metrics";
655  for (auto& metric : metric_plugins_)
656  {
657  if (!metric)
658  {
659  continue;
660  }
661  metric->sendMetrics(false, processing_start);
662  }
663 
664  // Limit rate of metrics going to plugins
665  TLOG(TLVL_DEBUG + 3) << "sendMetricLoop_: End of working loop";
666  busy_ = false;
667  usleep(10000);
668  }
669 
670  busy_ = true;
671  auto temp_list = std::list<std::unique_ptr<MetricData>>();
672  {
673  std::lock_guard<std::mutex> lk(metric_cache_mutex_);
674 
675  for (auto& q : metric_cache_)
676  {
677  if (q.second != nullptr && q.second->DataPointCount > 0)
678  {
679  temp_list.emplace_back(new MetricData(*q.second));
680  q.second->Reset();
681  }
682  }
683  //metric_cache_.clear();
684  }
685 
686  auto calls = metric_calls_.exchange(0);
687  temp_list.emplace_back(
688  new MetricData("Metric Calls", calls, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
689 
690  auto missed = missed_metric_calls_.exchange(0);
691  temp_list.emplace_back(
692  new MetricData("Missed Metric Calls", missed, "metrics", 4, MetricMode::Accumulate | MetricMode::Rate, "", false));
693 
694  TLOG(TLVL_TRACE) << "There are " << temp_list.size() << " Metrics to process (" << calls << " calls, " << missed
695  << " missed)";
696 
697  while (!temp_list.empty())
698  {
699  auto data_ = std::move(temp_list.front());
700  temp_list.pop_front();
701  if (data_->Type == MetricType::InvalidMetric)
702  {
703  continue;
704  }
705  if (!data_->UseNameOverride)
706  {
707  if (!data_->MetricPrefix.empty())
708  {
709  data_->Name = prefix_ + "." + data_->MetricPrefix + "." + data_->Name;
710  }
711  else
712  {
713  data_->Name = prefix_ + "." + data_->Name;
714  }
715  }
716 
717  for (auto& metric : metric_plugins_)
718  {
719  if (!metric)
720  {
721  continue;
722  }
723  if (metric->IsLevelEnabled(data_->Level))
724  {
725  try
726  {
727  metric->addMetricData(data_);
728  last_send_time = std::chrono::steady_clock::now();
729  }
730  catch (...)
731  {
732  TLOG(TLVL_ERROR) << "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
733  << metric->getLibName();
734  }
735  }
736  }
737  }
738 
739  for (auto& metric : metric_plugins_)
740  {
741  if (!metric)
742  {
743  continue;
744  }
745  try
746  {
747  metric->stopMetrics();
748  TLOG(TLVL_DEBUG) << "Metric Plugin " << metric->getLibName() << " stopped.";
749  }
750  catch (...)
751  {
752  TLOG(TLVL_ERROR) << "Exception caught in MetricManager::do_stop(), error stopping plugin with name "
753  << metric->getLibName();
754  }
755  }
756  busy_ = false;
757  TLOG(TLVL_DEBUG) << "MetricManager has been stopped.";
758 }
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
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.