artdaq_utilities  v1_07_00
report_metric.cc
1 // report_metric.cc: Periodic Report Metric Plugin
2 // Author: Eric Flumerfelt
3 // Last Modified: 11/06/2014
4 //
5 // An implementation of the MetricPlugin for creating "Periodic Report" messages
6 
7 #include "TRACE/tracemf.h" // order matters -- trace.h (no "mf") is nested from MetricMacros.hh
8 #define TRACE_NAME (app_name_ + "_report_metric").c_str()
9 
10 #include "artdaq-utilities/Plugins/MetricMacros.hh"
11 #include "fhiclcpp/ParameterSet.h"
12 
13 #include <sys/types.h>
14 #include <unistd.h>
15 #include <ctime>
16 #include <fstream>
17 #include <mutex>
18 #include <sstream>
19 #include <string>
20 #include "tracemf.h"
21 
22 namespace artdaq {
26 class PeriodicReportMetric final : public MetricPlugin
27 {
28 private:
29  std::chrono::steady_clock::time_point last_report_time_;
30 
31  std::map<std::string, std::string> metrics_;
32 
33  std::mutex report_mutex_;
34 
35 public:
46  explicit PeriodicReportMetric(fhicl::ParameterSet const& config, std::string const& app_name, std::string const& metric_name)
47  : MetricPlugin(config, app_name, metric_name)
48  , last_report_time_(std::chrono::steady_clock::now())
49 
50  {
51  startMetrics();
52  }
53 
58  {
59  stopMetrics();
60  }
61 
66  std::string getLibName() const override { return "report"; }
67 
76  void sendMetric_(const std::string& name, const std::string& value, const std::string& unit, const std::chrono::system_clock::time_point&) override
77  {
78  if (!inhibit_)
79  {
80  metrics_[name] = value + " " + unit;
81  writeReportMessage_(false);
82  }
83  }
84 
92  void sendMetric_(const std::string& name, const int& value, const std::string& unit, const std::chrono::system_clock::time_point& time) override
93  {
94  sendMetric_(name, std::to_string(value), unit, time);
95  }
96 
104  void sendMetric_(const std::string& name, const double& value, const std::string& unit, const std::chrono::system_clock::time_point& time) override
105  {
106  sendMetric_(name, std::to_string(value), unit, time);
107  }
108 
116  void sendMetric_(const std::string& name, const float& value, const std::string& unit, const std::chrono::system_clock::time_point& time) override
117  {
118  sendMetric_(name, std::to_string(value), unit, time);
119  }
120 
128  void sendMetric_(const std::string& name, const uint64_t& value, const std::string& unit, const std::chrono::system_clock::time_point& time) override
129  {
130  sendMetric_(name, std::to_string(value), unit, time);
131  }
132 
136  void startMetrics_() override
137  {
138  }
139 
143  void stopMetrics_() override
144  {
145  writeReportMessage_(true);
146  metrics_.clear();
147  }
148 
149 private:
152  PeriodicReportMetric& operator=(const PeriodicReportMetric&) = delete;
153  PeriodicReportMetric& operator=(PeriodicReportMetric&&) = delete;
154 
155  void writeReportMessage_(bool force)
156  {
157  std::unique_lock<std::mutex> lk(report_mutex_);
158  if (force || std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(std::chrono::steady_clock::now() - last_report_time_).count() >= accumulationTime_)
159  {
160  if (metrics_.empty())
161  {
162  return;
163  }
164  last_report_time_ = std::chrono::steady_clock::now();
165  std::ostringstream str;
166 
167  int count = 0;
168  int live_metrics = 0;
169  for (auto& metric : metrics_)
170  {
171  if (count != 0)
172  {
173  str << "," << std::endl;
174  }
175  str << "\t" << metric.first << ": " << metric.second;
176  if (metric.second != "NOT REPORTED")
177  {
178  live_metrics++;
179  }
180  metric.second = "NOT REPORTED";
181  count++;
182  }
183  if (live_metrics > 0)
184  {
185  METLOG(TLVL_INFO) << "Periodic report: " << live_metrics << " active metrics:" << std::endl
186  << str.str();
187  }
188  else
189  {
190  TLOG_INFO(app_name_) << "Periodic report: No active metrics in last reporting interval!";
191  METLOG(TLVL_INFO) << "Periodic report: No active metrics in last reporting interval!";
192  }
193  }
194  }
195 };
196 } //End namespace artdaq
197 
198 DEFINE_ARTDAQ_METRIC(artdaq::PeriodicReportMetric)
The MetricPlugin class defines the interface that MetricManager uses to send metric data to the vario...
Definition: MetricPlugin.hh:41
PeriodicReportMetric(fhicl::ParameterSet const &config, std::string const &app_name, std::string const &metric_name)
PeriodicReportMetric Constructor.
void startMetrics()
Perform startup actions. Simply calls the virtual startMetrics_ function.
void sendMetric_(const std::string &name, const int &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
void sendMetric_(const std::string &name, const std::string &value, const std::string &unit, const std::chrono::system_clock::time_point &) override
Write metric data to a file.
void sendMetric_(const std::string &name, const uint64_t &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
void sendMetric_(const std::string &name, const double &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
void stopMetrics()
Perform shutdown actions. Zeroes out all accumulators, and sends zeros for each metric. Calls stopMetrics_() for any plugin-defined shutdown actions.
std::string app_name_
Name of the application which is sending metrics to this plugin.
void sendMetric_(const std::string &name, const float &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
std::string getLibName() const override
Get the library name for the PeriodicReport metric.
PeriodicReportMetric writes metric data to a file on disk.
void startMetrics_() override
Perform startup actions.
void stopMetrics_() override
Perform shutdown actions.
double accumulationTime_
The amount of time to average metric values; except for accumulate=false metrics, will be the interva...
~PeriodicReportMetric() override
PeriodicReportMetric Destructor. Calls stopMetrics and then closes the file.
bool inhibit_
Flag to indicate that the MetricPlugin is being stopped, and any metric back-ends which do not have a...