8 #ifndef __METRIC_INTERFACE__
9 #define __METRIC_INTERFACE__
13 #include <unordered_map>
14 #include "fhiclcpp/ParameterSet.h"
15 #include "fhiclcpp/types/Atom.h"
16 # include "fhiclcpp/types/ConfigurationTable.h"
18 #include "artdaq-utilities/Plugins/MetricData.hh"
19 #include "cetlib/compiler_macros.h"
21 #define FALLTHROUGH while(0)
39 fhicl::Atom<std::string>
metricPluginType{ fhicl::Name{
"metricPluginType"}, fhicl::Comment{
"The name of the metric plugin to load (may have additional configuration parameters"} };
41 fhicl::Atom<int>
level{ fhicl::Name{
"level"}, fhicl::Comment{
"The verbosity level threshold for this plugin. Metrics with verbosity level greater than this will not be sent to the plugin"}, 0 };
43 fhicl::Atom<double>
reporting_interval{ fhicl::Name{
"reporting_interval"}, fhicl::Comment{
"How often recorded metrics are sent to the underlying metric storage"}, 15.0 };
45 using Parameters = fhicl::WrappedTable<Config>;
61 explicit MetricPlugin(fhicl::ParameterSet
const& ps, std::string
const& app_name) :
pset(ps)
72 virtual ~MetricPlugin() =
default;
83 virtual std::string getLibName()
const {
return "ERROR"; }
93 virtual void sendMetric_(
const std::string& name,
const std::string& value,
const std::string& unit) = 0;
103 virtual void sendMetric_(
const std::string& name,
const int& value,
const std::string& unit) = 0;
113 virtual void sendMetric_(
const std::string& name,
const double& value,
const std::string& unit) = 0;
123 virtual void sendMetric_(
const std::string& name,
const float& value,
const std::string& unit) = 0;
133 virtual void sendMetric_(
const std::string& name,
const long unsigned int& value,
const std::string& unit) = 0;
140 virtual void startMetrics_() = 0;
147 virtual void stopMetrics_() = 0;
159 void addMetricData(MetricData data)
163 sendMetric_(data.Name, data.StringValue, data.Unit);
167 if (!metricRegistry_.count(data.Name))
169 metricRegistry_[data.Name] = data;
171 metricData_[data.Name].push_back(data);
181 void sendMetrics(
bool forceSend =
false, std::chrono::steady_clock::time_point interval_end = std::chrono::steady_clock::now())
188 for (
auto metric : metricData_)
190 auto *metricName = &metric.first;
191 if (readyToSend_(*metricName) || forceSend)
193 if (metricData_[*metricName].size() == 0 && metricRegistry_.count(*metricName))
195 sendZero_(metricRegistry_[*metricName]);
197 else if (metricData_[*metricName].size() > 0)
199 auto metricMode = &metricData_[*metricName].back().Mode;
200 auto metricUnits = &metricData_[*metricName].back().Unit;
201 auto metricType = &metricData_[*metricName].back().Type;
205 if (metricData_[*metricName].size() > 1)
207 metricData_[*metricName].erase(metricData_[*metricName].begin(), std::prev(metricData_[*metricName].end()));
209 sendMetric_(metricData_[*metricName].back());
218 for (
auto& mv : metricData_[*metricName]) { ds += mv.DoubleValue; }
221 case MetricMode::Average: ds /=
static_cast<double>(metricData_[*metricName].size());
break;
222 case MetricMode::Rate: ds /= std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count();
break;
223 case MetricMode::AccumulateAndRate: sendMetric_(*metricName +
" - Rate", ds / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count(), *metricUnits +
"/s");
break;
227 sendMetric_(*metricName, ds, *metricUnits);
233 for (
auto& mv : metricData_[*metricName]) { fs += mv.FloatValue; }
238 ds = fs /
static_cast<double>(metricData_[*metricName].size());
239 sendMetric_(*metricName, ds, *metricUnits);
242 ds = fs / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count();
243 sendMetric_(*metricName, ds, *metricUnits);
246 sendMetric_(*metricName +
" - Rate", fs / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count(), *metricUnits +
"/s");
250 sendMetric_(*metricName, fs, *metricUnits);
258 for (
auto& mv : metricData_[*metricName]) { is += mv.IntValue; }
263 ds = is /
static_cast<double>(metricData_[*metricName].size());
264 sendMetric_(*metricName, ds, *metricUnits);
267 ds = is / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count();
268 sendMetric_(*metricName, ds, *metricUnits);
271 sendMetric_(*metricName +
" - Rate", is / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count(), *metricUnits +
"/s");
275 sendMetric_(*metricName, is, *metricUnits);
283 for (
auto& mv : metricData_[*metricName]) { us += mv.UnsignedValue; }
288 ds = us /
static_cast<double>(metricData_[*metricName].size());
289 sendMetric_(*metricName, ds, *metricUnits);
292 ds = us / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count();
293 sendMetric_(*metricName, ds, *metricUnits);
296 sendMetric_(*metricName +
" - Rate", us / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[*metricName]).count(), *metricUnits +
"/s");
300 sendMetric_(*metricName, us, *metricUnits);
308 metricData_[*metricName].clear();
311 interval_start_[*metricName] = interval_end;
319 void startMetrics() { startMetrics_(); }
329 for (
auto metric : metricRegistry_)
331 sendZero_(metric.second);
341 void setRunLevel(
int level) {
runLevel_ = level; }
346 int getRunLevel()
const {
return runLevel_; }
356 std::unordered_map<std::string, std::list<MetricData>> metricData_;
357 std::unordered_map<std::string, MetricData> metricRegistry_;
358 std::unordered_map<std::string, std::chrono::steady_clock::time_point> lastSendTime_;
359 std::unordered_map<std::string, std::chrono::steady_clock::time_point> interval_start_;
361 bool readyToSend_(std::string name)
363 auto now = std::chrono::steady_clock::now();
364 if (std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(now - lastSendTime_[name]).count() >=
accumulationTime_)
366 lastSendTime_[name] = now;
378 sendMetric_(data.
Name, static_cast<double>(0.0), data.
Unit);
381 sendMetric_(data.
Name, static_cast<float>(0.0), data.
Unit);
384 sendMetric_(data.
Name, static_cast<int>(0), data.
Unit);
387 sendMetric_(data.
Name, static_cast<unsigned long>(0), data.
Unit);
395 sendMetric_(data.
Name +
" - Rate", static_cast<double>(0.0), data.
Unit +
"/s");
399 void sendMetric_(MetricData data)
404 sendMetric_(data.Name, data.DoubleValue, data.Unit);
407 sendMetric_(data.Name, data.FloatValue, data.Unit);
410 sendMetric_(data.Name, data.IntValue, data.Unit);
413 sendMetric_(data.Name, data.UnsignedValue, data.Unit);
422 #endif //End ifndef __METRIC_INTERFACE__
Report the average of all values. Use for rates to report accurate results.
fhicl::ParameterSet pset
The ParameterSet used to configure the MetricPlugin.
fhicl::Atom< std::string > metricPluginType
The name of the metric plugin to load (may have additional configuration parameters.
std::string Unit
Units of the metric
Metric is a std::string (not in union)
std::string Name
Name of the metric
fhicl::Atom< double > reporting_interval
"reporting_interval" (Default: 15.0): The interval, in seconds, which the metric plugin will accumula...
Reports the sum of all values, divided by the length of the time interval they were accumulated over...
MetricMode Mode
Accumulation mode of the metric
fhicl::Atom< int > level
"level" (Default: 0): The verbosity level of the metric plugin. Higher number = fewer metrics sent to...
std::string app_name_
Name of the application which is sending metrics to this plugin.
Metric is a long unsigned int.
Sends both the Accumulate mode and Rate mode metric. (Rate mode metric will append "/s" to metric uni...
MetricType Type
Type of the metric
Report the sum of all values. Use for counters to report accurate results.
double accumulationTime_
The amount of time to average metric values; except for accumulate=false metrics, will be the interva...
Small structure used to hold a metric data point before sending to the metric plugins ...
Report only the last value recorded. Useful for event counters, run numbers, etc. ...
bool inhibit_
Whether to inhibit all metric sending.
int runLevel_
The threshold for sending metrics to the underlying storage. Metrics with level <= to runLevel_ will ...