00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "artdaq-utilities/Plugins/MetricManager.hh"
00010 #include "artdaq-utilities/Plugins/makeMetricPlugin.hh"
00011 #include "messagefacility/MessageLogger/MessageLogger.h"
00012 #include "fhiclcpp/ParameterSet.h"
00013
00014 #include <chrono>
00015 #include <boost/exception/all.hpp>
00016
00017 artdaq::MetricManager::
00018 MetricManager() : metric_plugins_(0)
00019 , initialized_(false)
00020 , running_(false)
00021 , active_(false) { }
00022
00023 artdaq::MetricManager::~MetricManager()
00024 {
00025 shutdown();
00026 }
00027
00028 void artdaq::MetricManager::initialize(fhicl::ParameterSet const& pset, std::string prefix)
00029 {
00030 prefix_ = prefix;
00031 if (initialized_)
00032 {
00033 shutdown();
00034 }
00035 mf::LogDebug("MetricManager") << "Configuring metrics with parameter set:\n" << pset.to_string();
00036
00037 std::vector<std::string> names = pset.get_pset_names();
00038
00039 for (auto name : names)
00040 {
00041 try
00042 {
00043 mf::LogDebug("MetricManager") << "Constructing metric plugin with name " << name;
00044 fhicl::ParameterSet plugin_pset = pset.get<fhicl::ParameterSet>(name);
00045 metric_plugins_.push_back(makeMetricPlugin(
00046 plugin_pset.get<std::string>("metricPluginType", ""), plugin_pset));
00047 }
00048 catch (const cet::exception& e)
00049 {
00050 mf::LogError("MetricManager") << "Exception caught in MetricManager::initialize, error loading plugin with name " << name <<
00051 ", cet::exception object caught:" << e.explain_self();
00052 }
00053 catch (const boost::exception& e)
00054 {
00055 mf::LogError("MetricManager") << "Exception caught in MetricManager::initialize, error loading plugin with name " << name <<
00056 ", boost::exception object caught: " << boost::diagnostic_information(e);
00057 }
00058 catch (const std::exception& e)
00059 {
00060 mf::LogError("MetricManager") << "Exception caught in MetricManager::initialize, error loading plugin with name " << name <<
00061 ", std::exception caught: " << e.what();
00062 }
00063 catch (...)
00064 {
00065 mf::LogError("MetricManager") << "Unknown Exception caught in MetricManager::initialize, error loading plugin with name " << name;
00066 }
00067 }
00068
00069 initialized_ = true;
00070 }
00071
00072 void artdaq::MetricManager::do_start()
00073 {
00074 if (!running_)
00075 {
00076 mf::LogDebug("MetricManager") << "Starting MetricManager";
00077 for (auto& metric : metric_plugins_)
00078 {
00079 try
00080 {
00081 metric->startMetrics();
00082 mf::LogDebug("MetricManager") << "Metric Plugin " << metric->getLibName() << " started.";
00083 active_ = true;
00084 }
00085 catch (...)
00086 {
00087 mf::LogError("MetricManager") <<
00088 "Exception caught in MetricManager::do_start(), error starting plugin with name " <<
00089 metric->getLibName();
00090 }
00091 }
00092 running_ = true;
00093 startMetricLoop_();
00094 }
00095 }
00096
00097 void artdaq::MetricManager::do_stop()
00098 {
00099 running_ = false;
00100 metric_cv_.notify_all();
00101 if (metric_sending_thread_.joinable()) metric_sending_thread_.join();
00102 }
00103
00104 void artdaq::MetricManager::do_pause() { }
00105 void artdaq::MetricManager::do_resume() { }
00106
00107 void artdaq::MetricManager::reinitialize(fhicl::ParameterSet const& pset, std::string prefix)
00108 {
00109 shutdown();
00110 initialize(pset, prefix);
00111 }
00112
00113 void artdaq::MetricManager::shutdown()
00114 {
00115 mf::LogDebug("MetricManager") << "MetricManager is shutting down...";
00116 do_stop();
00117
00118 if (initialized_)
00119 {
00120 for (auto& i : metric_plugins_)
00121 {
00122 try
00123 {
00124 std::string name = i->getLibName();
00125 i.reset(nullptr);
00126 mf::LogDebug("MetricManager") << "Metric Plugin " << name << " shutdown.";
00127 }
00128 catch (...)
00129 {
00130 mf::LogError("MetricManager") <<
00131 "Exception caught in MetricManager::shutdown(), error shutting down metric with name " <<
00132 i->getLibName();
00133 }
00134 }
00135 initialized_ = false;
00136 }
00137 }
00138
00139 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)
00140 {
00141 if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
00142 else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
00143 else if (active_)
00144 {
00145 std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
00146 {
00147 std::unique_lock<std::mutex> lk(metric_queue_mutex_);
00148 metric_queue_.push_back(std::move(metric));
00149 }
00150 metric_cv_.notify_all();
00151 }
00152 }
00153
00154 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)
00155 {
00156 if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
00157 else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
00158 else if (active_)
00159 {
00160 std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
00161 {
00162 std::unique_lock<std::mutex> lk(metric_queue_mutex_);
00163 metric_queue_.push_back(std::move(metric));
00164 }
00165 metric_cv_.notify_all();
00166 }
00167 }
00168
00169 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)
00170 {
00171 if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
00172 else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
00173 else if (active_)
00174 {
00175 std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
00176 {
00177 std::unique_lock<std::mutex> lk(metric_queue_mutex_);
00178 metric_queue_.push_back(std::move(metric));
00179 }
00180 metric_cv_.notify_all();
00181 }
00182 }
00183
00184 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)
00185 {
00186 if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
00187 else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
00188 else if (active_)
00189 {
00190 std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
00191 {
00192 std::unique_lock<std::mutex> lk(metric_queue_mutex_);
00193 metric_queue_.push_back(std::move(metric));
00194 }
00195 metric_cv_.notify_all();
00196 }
00197 }
00198
00199 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)
00200 {
00201 if (!initialized_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager has not yet been initialized!";
00202 else if (!running_) mf::LogWarning("MetricManager") << "Attempted to send metric when MetricManager stopped!";
00203 else if (active_)
00204 {
00205 std::unique_ptr<MetricData> metric(new MetricData(name, value, unit, level, accumulate, metricPrefix, useNameOverride));
00206 {
00207 std::unique_lock<std::mutex> lk(metric_queue_mutex_);
00208 metric_queue_.push_back(std::move(metric));
00209 }
00210 metric_cv_.notify_all();
00211 }
00212 }
00213
00214 void artdaq::MetricManager::startMetricLoop_()
00215 {
00216 if (metric_sending_thread_.joinable()) metric_sending_thread_.join();
00217 mf::LogInfo("MetricManager") << "Starting Metric Sending Thread" << std::endl;
00218 metric_sending_thread_ = std::thread(&MetricManager::sendMetricLoop_, this);
00219 }
00220
00221 void artdaq::MetricManager::sendMetricLoop_()
00222 {
00223 while (running_)
00224 {
00225 while (metric_queue_.size() == 0 && running_)
00226 {
00227 std::unique_lock<std::mutex> lk(metric_mutex_);
00228 metric_cv_.wait_for(lk, std::chrono::milliseconds(100));
00229 }
00230
00231 auto temp_list = std::list<std::unique_ptr<MetricData>>();
00232 {
00233 std::unique_lock<std::mutex> lk(metric_queue_mutex_);
00234 temp_list.swap(metric_queue_);
00235 }
00236
00237 while (temp_list.size() > 0)
00238 {
00239 auto data_ = std::move(temp_list.front());
00240 temp_list.pop_front();
00241 if (data_->type_ == MetricData::InvalidMetric) continue;
00242 std::string nameTemp = data_->name_;
00243 if (!data_->useNameOverride_)
00244 {
00245 if (data_->metricPrefix_.size() > 0)
00246 {
00247 nameTemp = prefix_ + "." + data_->metricPrefix_ + "." + data_->name_;
00248 }
00249 else
00250 {
00251 nameTemp = prefix_ + "." + data_->name_;
00252 }
00253 }
00254
00255 for (auto& metric : metric_plugins_)
00256 {
00257 if (metric->getRunLevel() >= data_->level_)
00258 {
00259 try
00260 {
00261 switch (data_->type_)
00262 {
00263 case MetricData::StringMetric:
00264 metric->sendMetric(nameTemp, data_->stringValue_, data_->unit_, data_->accumulate_);
00265 break;
00266 case MetricData::IntMetric:
00267 metric->sendMetric(nameTemp, data_->intValue_, data_->unit_, data_->accumulate_);
00268 break;
00269 case MetricData::DoubleMetric:
00270 metric->sendMetric(nameTemp, data_->doubleValue_, data_->unit_, data_->accumulate_);
00271 break;
00272 case MetricData::FloatMetric:
00273 metric->sendMetric(nameTemp, data_->floatValue_, data_->unit_, data_->accumulate_);
00274 break;
00275 case MetricData::UnsignedMetric:
00276 metric->sendMetric(nameTemp, data_->unsignedValue_, data_->unit_, data_->accumulate_);
00277 break;
00278 case MetricData::InvalidMetric:
00279 break;
00280 }
00281 }
00282 catch (...)
00283 {
00284 mf::LogError("MetricManager") <<
00285 "Error in MetricManager::sendMetric: error sending value to metric plugin with name "
00286 << metric->getLibName();
00287 }
00288 }
00289 }
00290 }
00291 }
00292
00293 for (auto& metric : metric_plugins_)
00294 {
00295 try
00296 {
00297 metric->stopMetrics();
00298 mf::LogDebug("MetricManager") << "Metric Plugin " << metric->getLibName() << " stopped.";
00299 }
00300 catch (...)
00301 {
00302 mf::LogError("MetricManager") <<
00303 "Exception caught in MetricManager::do_stop(), error stopping plugin with name " <<
00304 metric->getLibName();
00305 }
00306 }
00307 mf::LogDebug("MetricManager") << "MetricManager has been stopped.";
00308 }