artdaq_utilities  v1_02_04
 All Classes Namespaces Functions Variables Typedefs
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 #include "artdaq-utilities/Plugins/MetricManager.hh"
10 #include "artdaq-utilities/Plugins/makeMetricPlugin.hh"
11 #include "messagefacility/MessageLogger/MessageLogger.h"
12 #include "fhiclcpp/ParameterSet.h"
13 
14 #include <chrono>
15 #include <boost/exception/all.hpp>
16 
18 MetricManager() : metric_plugins_(0)
19  , initialized_(false)
20  , running_(false)
21  , active_(false) { }
22 
24 {
25  shutdown();
26 }
27 
28 void artdaq::MetricManager::initialize(fhicl::ParameterSet const& pset, std::string prefix)
29 {
30  prefix_ = prefix;
31  if (initialized_)
32  {
33  shutdown();
34  }
35  mf::LogDebug("MetricManager") << "Configuring metrics with parameter set:\n" << pset.to_string();
36 
37  std::vector<std::string> names = pset.get_pset_names();
38 
39  for (auto name : names)
40  {
41  try
42  {
43  mf::LogDebug("MetricManager") << "Constructing metric plugin with name " << name;
44  fhicl::ParameterSet plugin_pset = pset.get<fhicl::ParameterSet>(name);
45  metric_plugins_.push_back(makeMetricPlugin(
46  plugin_pset.get<std::string>("metricPluginType", ""), plugin_pset));
47  }
48  catch (const cet::exception& e)
49  {
50  mf::LogError("MetricManager") << "Exception caught in MetricManager::initialize, error loading plugin with name " << name <<
51  ", cet::exception object caught:" << e.explain_self();
52  }
53  catch (const boost::exception& e)
54  {
55  mf::LogError("MetricManager") << "Exception caught in MetricManager::initialize, error loading plugin with name " << name <<
56  ", boost::exception object caught: " << boost::diagnostic_information(e);
57  }
58  catch (const std::exception& e)
59  {
60  mf::LogError("MetricManager") << "Exception caught in MetricManager::initialize, error loading plugin with name " << name <<
61  ", std::exception caught: " << e.what();
62  }
63  catch (...)
64  {
65  mf::LogError("MetricManager") << "Unknown Exception caught in MetricManager::initialize, error loading plugin with name " << name;
66  }
67  }
68 
69  initialized_ = true;
70 }
71 
73 {
74  if (!running_)
75  {
76  mf::LogDebug("MetricManager") << "Starting MetricManager";
77  for (auto& metric : metric_plugins_)
78  {
79  try
80  {
81  metric->startMetrics();
82  mf::LogDebug("MetricManager") << "Metric Plugin " << metric->getLibName() << " started.";
83  active_ = true;
84  }
85  catch (...)
86  {
87  mf::LogError("MetricManager") <<
88  "Exception caught in MetricManager::do_start(), error starting plugin with name " <<
89  metric->getLibName();
90  }
91  }
92  running_ = true;
93  startMetricLoop_();
94  }
95 }
96 
98 {
99  running_ = false;
100  metric_cv_.notify_all();
101  if (metric_sending_thread_.joinable()) metric_sending_thread_.join();
102 }
103 
104 void artdaq::MetricManager::do_pause() { /*do_stop();*/ }
105 void artdaq::MetricManager::do_resume() { /*do_start();*/ }
106 
107 void artdaq::MetricManager::reinitialize(fhicl::ParameterSet const& pset, std::string prefix)
108 {
109  shutdown();
110  initialize(pset, prefix);
111 }
112 
114 {
115  mf::LogDebug("MetricManager") << "MetricManager is shutting down...";
116  do_stop();
117 
118  if (initialized_)
119  {
120  for (auto& i : metric_plugins_)
121  {
122  try
123  {
124  std::string name = i->getLibName();
125  i.reset(nullptr);
126  mf::LogDebug("MetricManager") << "Metric Plugin " << name << " shutdown.";
127  }
128  catch (...)
129  {
130  mf::LogError("MetricManager") <<
131  "Exception caught in MetricManager::shutdown(), error shutting down metric with name " <<
132  i->getLibName();
133  }
134  }
135  initialized_ = false;
136  }
137 }
138 
139 void artdaq::MetricManager::sendMetric(std::string const& name, std::string const& value, std::string const& unit, int level, bool accumulate, std::string const& metricPrefix, bool useNameOverride)
140 {
141  if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
142  else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
143  else if (active_)
144  {
145  std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
146  {
147  std::unique_lock<std::mutex> lk(metric_queue_mutex_);
148  metric_queue_.push_back(std::move(metric));
149  }
150  metric_cv_.notify_all();
151  }
152 }
153 
154 void artdaq::MetricManager::sendMetric(std::string const& name, int const& value, std::string const& unit, int level, bool accumulate, std::string const& metricPrefix, bool useNameOverride)
155 {
156  if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
157  else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
158  else if (active_)
159  {
160  std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
161  {
162  std::unique_lock<std::mutex> lk(metric_queue_mutex_);
163  metric_queue_.push_back(std::move(metric));
164  }
165  metric_cv_.notify_all();
166  }
167 }
168 
169 void artdaq::MetricManager::sendMetric(std::string const& name, double const& value, std::string const& unit, int level, bool accumulate, std::string const& metricPrefix, bool useNameOverride)
170 {
171  if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
172  else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
173  else if (active_)
174  {
175  std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
176  {
177  std::unique_lock<std::mutex> lk(metric_queue_mutex_);
178  metric_queue_.push_back(std::move(metric));
179  }
180  metric_cv_.notify_all();
181  }
182 }
183 
184 void artdaq::MetricManager::sendMetric(std::string const& name, float const& value, std::string const& unit, int level, bool accumulate, std::string const& metricPrefix, bool useNameOverride)
185 {
186  if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
187  else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
188  else if (active_)
189  {
190  std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
191  {
192  std::unique_lock<std::mutex> lk(metric_queue_mutex_);
193  metric_queue_.push_back(std::move(metric));
194  }
195  metric_cv_.notify_all();
196  }
197 }
198 
199 void artdaq::MetricManager::sendMetric(std::string const& name, long unsigned int const& value, std::string const& unit, int level, bool accumulate, std::string const& metricPrefix, bool useNameOverride)
200 {
201  if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
202  else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
203  else if (active_)
204  {
205  std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
206  {
207  std::unique_lock<std::mutex> lk(metric_queue_mutex_);
208  metric_queue_.push_back(std::move(metric));
209  }
210  metric_cv_.notify_all();
211  }
212 }
213 
214 void artdaq::MetricManager::startMetricLoop_()
215 {
216  if (metric_sending_thread_.joinable()) metric_sending_thread_.join();
217  mf::LogInfo("MetricManager") << "Starting Metric Sending Thread" << std::endl;
218  metric_sending_thread_ = std::thread(&MetricManager::sendMetricLoop_, this);
219 }
220 
221 void artdaq::MetricManager::sendMetricLoop_()
222 {
223  while (running_)
224  {
225  while (metric_queue_.size() == 0 && running_)
226  {
227  std::unique_lock<std::mutex> lk(metric_mutex_);
228  metric_cv_.wait_for(lk, std::chrono::milliseconds(100));
229  }
230 
231  auto temp_list = std::list<std::unique_ptr<MetricData>>();
232  {
233  std::unique_lock<std::mutex> lk(metric_queue_mutex_);
234  temp_list.swap(metric_queue_);
235  }
236 
237  while (temp_list.size() > 0)
238  {
239  auto data_ = std::move(temp_list.front());
240  temp_list.pop_front();
241  if (data_->type_ == MetricData::InvalidMetric) continue;
242  std::string nameTemp = data_->name_;
243  if (!data_->useNameOverride_)
244  {
245  if (data_->metricPrefix_.size() > 0)
246  {
247  nameTemp = prefix_ + "." + data_->metricPrefix_ + "." + data_->name_;
248  }
249  else
250  {
251  nameTemp = prefix_ + "." + data_->name_;
252  }
253  }
254 
255  for (auto& metric : metric_plugins_)
256  {
257  if (metric->getRunLevel() >= data_->level_)
258  {
259  try
260  {
261  switch (data_->type_)
262  {
263  case MetricData::StringMetric:
264  metric->sendMetric(nameTemp, data_->stringValue_, data_->unit_, data_->accumulate_);
265  break;
266  case MetricData::IntMetric:
267  metric->sendMetric(nameTemp, data_->intValue_, data_->unit_, data_->accumulate_);
268  break;
269  case MetricData::DoubleMetric:
270  metric->sendMetric(nameTemp, data_->doubleValue_, data_->unit_, data_->accumulate_);
271  break;
272  case MetricData::FloatMetric:
273  metric->sendMetric(nameTemp, data_->floatValue_, data_->unit_, data_->accumulate_);
274  break;
275  case MetricData::UnsignedMetric:
276  metric->sendMetric(nameTemp, data_->unsignedValue_, data_->unit_, data_->accumulate_);
277  break;
278  case MetricData::InvalidMetric:
279  break;
280  }
281  }
282  catch (...)
283  {
284  mf::LogError("MetricManager") <<
285  "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
286  << metric->getLibName();
287  }
288  }
289  }
290  }
291  }
292 
293  for (auto& metric : metric_plugins_)
294  {
295  try
296  {
297  metric->stopMetrics();
298  mf::LogDebug("MetricManager") << "Metric Plugin " << metric->getLibName() << " stopped.";
299  }
300  catch (...)
301  {
302  mf::LogError("MetricManager") <<
303  "Exception caught in MetricManager::do_stop(), error stopping plugin with name " <<
304  metric->getLibName();
305  }
306  }
307  mf::LogDebug("MetricManager") << "MetricManager has been stopped.";
308 }
void reinitialize(fhicl::ParameterSet const &pset, std::string prefix="")
Reinitialize all MetricPlugin Instances.
void shutdown()
Call the destructors for all configured MetricPlugin instances.
void initialize(fhicl::ParameterSet const &pset, std::string prefix="")
Initialize the MetricPlugin instances.
std::unique_ptr< MetricPlugin > makeMetricPlugin(std::string const &generator_plugin_spec, fhicl::ParameterSet const &ps)
Load a given MetricPlugin and return a pointer to it.
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.
void do_resume()
Resume metric sending. Currently a No-Op.
void sendMetric(std::string const &name, std::string const &value, std::string const &unit, int level, bool accumulate=true, std::string const &metricPrefix="", bool useNameOverride=false)
Send a metric with the given parameters to any MetricPlugins with a threshold level &gt;= to level...
void do_pause()
Pause metric sending. Currently a No-Op.