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