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